POJ 1201 & HDU1384 & ZOJ 1508 Intervals 差分约束

来源:互联网 发布:nero10刻录软件怎么用 编辑:程序博客网 时间:2024/06/04 17:43

题意:给定n个左右均为闭的区间[a,b],及一个对应的c,意思是从[a,b]中至少要选c个数,现在问要使得所有n个区间均满足上面的条件,至少需要选几个点。

思路:假定t[I]代表是否选取,1为选取,0为不选.设si = t[0]+t[1]+...+t[I]。则s[I-1] - s[I]>=-1,s[I]-s[I-1]>=0.因为s[I]-s[I-1]等于0或1.s[b]-s[a-1]>=c.由这三个条件建图

差分约束:https://wenku.baidu.com/view/b061cb986bec0975f465e234.html

#include<cstdio>#include<cstring>#include<vector>#include<queue>using namespace std;const int maxn = 50010;const int INF = 1<<30;int n,num,left;struct edge{int from,to,w;};vector<edge> edges;vector<int> g[maxn];int inq[maxn],d[maxn],cnt[maxn];void addedge(int from,int to,int w){edges.push_back(edge{from,to,w});int m = edges.size();g[from].push_back(m-1);}bool bellman_ford(int s){queue<int> q;q.push(s);memset(cnt,0,sizeof(cnt));memset(inq,0,sizeof(inq));for(int i=0;i<=num;i++)d[i]=INF;d[s]=0;inq[s]=1;while(!q.empty()){int u = q.front();q.pop();inq[u]=0;for(int i=0;i<g[u].size();i++){edge &e=edges[g[u][i]];if(d[e.to]>d[u]+e.w){d[e.to]=d[u]+e.w;if(!inq[e.to]){q.push(e.to);inq[e.to]=1;if(++cnt[e.to]>n)return false;}}}}return true;}int main(){while(scanf("%d",&n)!=EOF){for(int i=left-1;i<=num;i++)g[i].clear();edges.clear();num=-(1<<30);left=1<<30;for(int i=0;i<n;i++){int a,b,c;scanf("%d%d%d",&a,&b,&c);addedge(b,a-1,-c);if(b>num)num=b;if(a<left)left=a;}for(int i=left;i<=num;i++){addedge(i,i-1,0);addedge(i-1,i,1);}bellman_ford(num);printf("%d\n",-d[left-1]);}}

0 0
原创粉丝点击