POJ 1201 Intervals(差分约束)
第一个差分约束的题目。看了好多的博客,差分约束就是根据不等式建好图,然后求最短路或者最长路即可,很明显建图是关键。
这个题的题意是,给很多的区间,每个区间上至少ci个数,问最这些数最少有多少个。
这个题解讲的不错http://www.cnblogs.com/jiai/archive/2012/09/20/2696007.html
建图的的时候,不等式的方向要全部相同。s[i+1]表示这个集合在[1-i]的个数
s[bi+1] - s[ai] >= ci;//题目中给出
s[i+1] - s[i] >=0;//隐藏条件
s[i] - s[i+1] >= -1;
求s[maxz] - s[minz] >= ans;
建图就是求minz 到maxz的最长路。
1 #include <iostream> 2 #include <cstdio> 3 #include <cmath> 4 #include <cstring> 5 #include <queue> 6 using namespace std; 7 #define N 1000001 8 #define INF 0x7fffff 9 struct node 10 { 11 int u,v,next,w; 12 }edge[N]; 13 int first[N],t,maxz,minz; 14 int in[N],d[N]; 15 void CL() 16 { 17 t = 1; 18 memset(first,-1,sizeof(first)); 19 } 20 void add(int u,int v,int w) 21 { 22 edge[t].u = u; 23 edge[t].v = v; 24 edge[t].w = w; 25 edge[t].next = first[u]; 26 first[u] = t; 27 t ++; 28 } 29 void spfa(int str)//spfa模版 30 { 31 int i,v,u; 32 queue<int> que; 33 for(i = minz;i <= maxz;i ++) 34 { 35 in[i] = 0; 36 d[i] = -INF; 37 } 38 que.push(str); 39 in[str] = 1; 40 d[str] = 0; 41 while(!que.empty()) 42 { 43 u = que.front(); 44 in[u] = 0; 45 que.pop(); 46 for(i = first[u];i != -1;i = edge[i].next) 47 { 48 v = edge[i].v; 49 if(d[v] < d[u]+edge[i].w) 50 { 51 d[v] = d[u]+edge[i].w; 52 if(!in[v]) 53 { 54 in[v] = i; 55 que.push(v); 56 } 57 } 58 } 59 } 60 } 61 int main() 62 { 63 int n,i,sv,ev,w; 64 maxz = -1; 65 minz = 50001; 66 CL(); 67 scanf("%d",&n); 68 for(i = 1;i <= n;i ++) 69 { 70 scanf("%d%d%d",&sv,&ev,&w); 71 minz = min(sv,minz); 72 maxz = max(ev+1,maxz); 73 add(sv,ev+1,w);//建图 74 } 75 for(i = minz;i <= maxz;i ++) 76 { 77 add(i,i+1,0);//建图 78 add(i+1,i,-1); 79 } 80 spfa(minz); 81 printf("%d\n",d[maxz]); 82 return 0; 83 }