POJ1201Intervals(差分约束)
题意
给出数轴上的n个区间[ai,bi],每个区间都是连续的int区间。
现在要在数轴上任意取一堆元素,构成一个元素集合V
要求每个区间[ai,bi]和元素集合V的交集至少有ci不同的元素
求集合V最小的元素个数。
题解
一眼望去差分约束。所以开始找约束条件。
设sum[i]为[1,i]闭区间的元素个数。
sum[b[i]]-sum[a[i]-1]>=c[i];
还有个隐含(显然)的约束条件:sum[i]-sum[i-1]>=0
然后跑最短路即可。
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<cmath> 5 #include<algorithm> 6 #include<queue> 7 using namespace std; 8 const int maxn=50101; 9 struct edge{ 10 int to,w,nxt; 11 }e[maxn*10]; 12 int n,cnt,head[maxn],dis[maxn],book[maxn]; 13 void add(int u,int v,int w){ 14 cnt++; 15 e[cnt].to=v; 16 e[cnt].nxt=head[u]; 17 e[cnt].w=w; 18 head[u]=cnt; 19 } 20 void spfa(){ 21 queue<int> q; 22 for(int i=1;i<=50001;i++){ 23 dis[i]=-9999999; 24 } 25 book[0]=1; 26 q.push(0); 27 while(!q.empty()){ 28 int u=q.front(); 29 q.pop(); 30 book[u]=0; 31 for(int i=head[u];i;i=e[i].nxt){ 32 int v=e[i].to; 33 if(dis[v]<dis[u]+e[i].w){ 34 dis[v]=dis[u]+e[i].w; 35 if(book[v]==0){ 36 book[v]=1; 37 q.push(v); 38 } 39 } 40 } 41 } 42 } 43 int main(){ 44 scanf("%d",&n); 45 for(int i=1;i<=n;i++){ 46 int u,v,w; 47 scanf("%d%d%d",&u,&v,&w); 48 u+=1; 49 v+=1; 50 add(u-1,v,w); 51 } 52 for(int i=1;i<=50001;i++){ 53 add(i-1,i,0); 54 add(i,i-1,-1); 55 } 56 spfa(); 57 printf("%d",dis[50001]); 58 return 0; 59 }