poj 1201 Intervals(差分约束)

来源:互联网 发布:无线条码扫描 软件 编辑:程序博客网 时间:2024/05/17 03:48

题目链接:http://poj.org/problem?id=1201

题意:给出多个区间[ai,bi],每个区间和集合S有ci个相同的元素,求集合s中至少有多少个元素。

dis[i]表示从源点到i的所有元素中与s相同的个数,那么可以得到dis[bi+1]=dis[ai]+ci,因为是闭区间,所以有bi+1。

但是为了保证图的连通性,仅仅依靠所给的数据是不够的,题目中暗藏一个隐含条件:

dis[i+1]-1<=dis[i];

dis[i]<=dis[i+1];

这样建图就能够保证图的连通,这里差分约束可以理解为最长路径。

#include<iostream>#include<cstdio>#include<stack>using namespace std;const int INF=0x3f3f3f3f;const int maxn=50010;int n,m;int e,head[maxn],dis[maxn];bool vis[maxn];struct node{int to;int w;int next;}edge[150010];void init(){e=0;memset(dis,-1,sizeof(dis));memset(head,-1,sizeof(head));}void addEdge(int u,int v,int w){edge[e].to=v,edge[e].w=w,edge[e].next=head[u];head[u]=e++;}int spfa(int src,int des){stack<int>S;S.push(src);vis[src]=1,dis[src]=0;while(!S.empty()){int u=S.top();S.pop(),vis[u]=0;for(int i=head[u];i!=-1;i=edge[i].next){int v=edge[i].to;if(dis[v]<dis[u]+edge[i].w){dis[v]=dis[u]+edge[i].w;if(!vis[v]){vis[v]=1;S.push(v);}}}}return dis[des];}int main(){#ifndef ONLINE_JUDGE    freopen("test.in","r",stdin);    freopen("test.out","w",stdout);#endif    while(~scanf("%d",&n)){    init();    int a,b,c;    int src=INF,des=-INF;    while(n--){    scanf("%d%d%d",&a,&b,&c);    addEdge(a,b+1,c);    if(a<src) src=a;    if(b+1>des) des=b+1;    }    for(int i=src;i<des;i++){    addEdge(i,i+1,0);    addEdge(i+1,i,-1);    }    int ans=spfa(src,des);    printf("%d\n",ans);    }    return 0;}


0 0
原创粉丝点击