1 /* 2 http://poj.org/problem?id=1201 3 题目的转换真的非常非常巧妙,让我再来梳理一下。本题的题意是给了我们一些区间,然后告诉每个区间中至少需要取Ci个数。 4 求出满足n个条件的集合C的最少的元素个数。 5 用dis[i+1]表示从最小值min 到i所选得最小数 6 则有 dis[i]-dis[j]<=-W(i,j); 7 此外还必须加上 8 1>=dis[i+1]-dis[i]>=0; 9 这样就构成了完整的差分约束系统 10 */ 11 #include<stdio.h> 12 #include<vector> 13 #include<iostream> 14 #include<queue> 15 #include<string.h> 16 using namespace std; 17 const int N=200000; 18 int n; 19 struct node 20 { 21 22 int y; 23 int w; 24 }; 25 vector<node>p[N]; 26 queue<int>Q; 27 int vis[N],dis[N],min1,max1; 28 void init() 29 { 30 memset(vis,0,sizeof(vis)); 31 32 for(int i=0;i<=max1+1;i++){dis[i]=999999;} 33 dis[min1]=0; 34 vis[min1]=1; 35 } 36 void insert(int x,int y,int z) 37 { 38 node q; 39 q.y=y; 40 q.w=z; 41 p[x].push_back(q); 42 } 43 void spfa(int x) 44 { 45 init(); 46 while(!Q.empty())Q.pop(); 47 Q.push(min1); 48 while(!Q.empty()) 49 { 50 51 int k=Q.front(); 52 Q.pop(); 53 vis[k]=0;//出来之后还可能再进 54 55 for(int i=0;i<p[k].size();i++) 56 { 57 int a=p[k][i].y; 58 int len=p[k][i].w; 59 if(dis[a]>dis[k]+len) 60 { 61 dis[a]=dis[k]+len; 62 if(!vis[a]) 63 { 64 vis[a]=1; 65 Q.push(a); 66 } 67 } 68 } 69 } 70 71 72 } 73 int main() 74 { 75 int i,x,y,z; 76 while(~scanf("%d",&n)) 77 { 78 for(i=0;i<=N;i++)p[i].clear(); 79 min1=999999; 80 max1=-999999; 81 for(i=0;i<n;i++) 82 { 83 scanf("%d%d%d",&x,&y,&z); 84 insert(x,y+1,-z); 85 if(min1>x)min1=x; 86 if(max1<y+1)max1=y+1; 87 } 88 for(i=min1;i<=max1;i++) 89 { 90 insert(i,i+1,0); 91 insert(i+1,i,1); 92 } 93 spfa(min1); 94 95 printf("%d\n",-dis[max1+1]); 96 97 } 98 }