Intervals POJ - 1201
考察:差分约束
对本蒟蒻来说想到怎么建立差分约束系统就即为不容易.
思路:
根据题目,求满足 ai <= x <= bi 至少有Ci个 的最小集合.在某个区间里至少有Ci 个,我们可以联想一波前缀和. 这个式子转化为前缀和为 sum[b] - sum[a-1] >= Ci n个条件就有n个不等式,根据不等式组很容易想到差分约束
还有一些限制条件,比如 sum[i] - sum[i-1] >=0 , sum[i] - sum[i-1] <= 1.
1 #include <iostream> 2 #include <cstring> 3 #include <queue> 4 #include <cstdio> 5 using namespace std; 6 typedef long long LL; 7 const int N = 50010; 8 int h[N],m,idx; 9 LL dist[N]; 10 bool st[N]; 11 struct Road{ 12 int fr,to,ne,w; 13 }road[N*3]; 14 void add(int a,int b,int c) 15 { 16 road[idx].w = c,road[idx].fr = a,road[idx].to = b,road[idx].ne = h[a],h[a] = idx++; 17 } 18 void spfa() 19 { 20 queue<int> q; 21 for(int i=1;i<N;i++) dist[i] = -1e14; 22 dist[0] = 0; 23 q.push(0); st[0] = 1; 24 while(q.size()) 25 { 26 int u = q.front(); 27 q.pop(); 28 st[u] = 0; 29 for(int i=h[u];~i;i=road[i].ne) 30 { 31 int v = road[i].to; 32 if(dist[v]<dist[u]+road[i].w) 33 { 34 dist[v] = dist[u]+road[i].w; 35 if(!st[v]) q.push(v),st[v] = 1; 36 } 37 } 38 } 39 } 40 int main() 41 { 42 scanf("%d",&m); 43 for(int i=0;i<=50001;i++) h[i] = -1; 44 for(int i=1;i<=50001;i++) add(i-1,i,0),add(i,i-1,-1); 45 while(m--) 46 { 47 int a,b,c; scanf("%d%d%d",&a,&b,&c); 48 add(a,b+1,c); 49 } 50 spfa(); 51 printf("%lld\n",dist[50001]); 52 return 0; 53 }