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 }
View Code

 

posted @ 2018-07-29 16:16  Xu-daxia  阅读(169)  评论(0编辑  收藏  举报