您的位置:首页 > 其它

HDU 1384 查分约束

2016-07-12 20:53 274 查看
点击打开链接

题意:给了n个区间,要求每个区间至少有C个数字出现,问满足的最小的数字个数

思路:用Si代表0到i的区间内的数字个数,然后可以写出查分约束方程,对于一个区间则Sa-S(b-1)>=C的,然后隐含的一个条件就是Si-S(i-1)>=0且<=1的,然后泡个最长路就行,对于查分约束系统求最大值是<=的形式,而求最小值则是>=的形式
#include <queue>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3fll;
const int maxn=50010;
int dis[maxn],head[maxn],n,k;
bool vis[maxn];
struct edge{
int to,w,next;
}E[maxn*10];
void add_edge(int u,int v,int w){
E[k].to=v;E[k].w=w;E[k].next=head[u];head[u]=k++;
}
void spfa(int S){
queue<int>que;
memset(dis,-inf,sizeof(dis));
memset(vis,0,sizeof(vis));
que.push(S);dis[S]=0;
while(!que.empty()){
int t=que.front();que.pop();
vis[t]=0;
for(int i=head[t];i!=-1;i=E[i].next){
if(dis[t]+E[i].w>dis[E[i].to]){
dis[E[i].to]=dis[t]+E[i].w;
if(!vis[E[i].to]){
vis[E[i].to]=1;
que.push(E[i].to);
}
}
}
}
}
int main(){
int u,v,c;
while(scanf("%d",&n)!=-1){
k=0;
memset(head,-1,sizeof(head));
int S=inf,T=-inf;
for(int i=0;i<n;i++){
scanf("%d%d%d",&u,&v,&c);
S=min(S,u-1);T=max(T,v);
add_edge(u-1,v,c);
}
for(int i=S+1;i<=T;i++){
add_edge(i-1,i,0);
add_edge(i,i-1,-1);
}
spfa(S);
printf("%d\n",dis[T]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: