You are given n closed, integer intervals [ai, bi] and n integers c1, ..., cn. 
Write a program that: 
reads the number of intervals, their end 
points and integers c1, ..., cn from the standard input, 
computes the 
minimal size of a set Z of integers which has at least ci common elements with 
interval [ai, bi], for each i=1,2,...,n, 
writes the answer to the standard 
output. 
题目大意:一个整数集合Z有n个区间,每个区间有3个值,ai,bi,ci代表,在区间[ai,bi]上至少有ci个整数属于集合Z,ci可以在区间内任意取不重复的点。
现在要满足所有区间的约束条件,问最少可选多少个点。 
 
The first line of the input contains an integer n (1 <= n <= 50000) -- 
the number of intervals. The following n lines describe the intervals. The 
(i+1)-th line of the input contains three integers ai, bi and ci separated by 
single spaces and such that 0 <= ai <= bi <= 50000 and 1 <= ci <= 
bi - ai+1. 
第一行一个整数n,表示区间个数 
以下n行描述区间,第i+1行,三个整数ai,bi,ci,由空格隔开,其中 0 <= ai <= bi <= 50000 且1 <= 
ci <= bi - ai+1. 
 
The output contains exactly one integer equal to the minimal size of set Z 
sharing at least ci elements with interval [ai, bi], for each i=1,2,...,n.
一行,输出满足要求序列的长度的最小值 
 
题目意思是说在{ai,bi}区间和Z点集有ci个共同元素,设Si表示区间{0,i}有多少个元素,那么根据题目意思:Sbi-Sai>=ci。但是我们发现这远远不够,根本没法将所有点连接起来。所以此时我们再看一下Si的定义,易写出0<=Si-S(i-1)<=1。
 1 #include<cstdio>  
 2 #include<cstring>  
 3 #include<cmath>  
 4 #include<algorithm>  
 5 using namespace std;  
 6 struct p{  
 7     int to,v,nxt;  
 8 }edge[500001];  
 9 int n,maxx,minn,cnt,a,b,c,dis[1000001],queue[10000001],heads[1000001],head,tail;  
10 bool vis[1000001]={0};  
11 int addEdge(int u,int v,int val)//链式前向星  
12 {  
13     edge[++cnt].to=v;  
14     edge[cnt].v=val;  
15     edge[cnt].nxt=heads[u];  
16     heads[u]=cnt;  
17 }  
18 int main()  
19 {  
20     scanf("%d",&n);  
21     maxx=-0x7fffffff,minn=0x7fffffff;  
22     for(int i=1;i<=n;i++)  
23     {  
24         scanf("%d%d%d",&a,&b,&c);  
25         addEdge(a-1,b,c);  
26         minn=min(minn,a-1);  
27         maxx=max(maxx,b);  
28     }  
29     for(int i=minn;i<=maxx;i++)  
30     {  
31         addEdge(i-1,i,0);  
32         addEdge(i,i-1,-1);  
33     }  
34     for(int i=0;i<=maxx;++i) dis[i]=-10000000; 
35     dis[minn]=0,queue[1]=minn,tail=1,vis[minn]=1;  
36     do
37     {  
38         head++;  
39         int node=queue[head];  
40         for(int i=heads[node];i!=0;i=edge[i].nxt)  
41         {  
42             int to=edge[i].to,val=edge[i].v;  
43             if(dis[to]<dis[node]+val)  
44             {  
45                 dis[to]=dis[node]+val;  
46                 if(!vis[to])  
47                 {  
48                     tail++;  
49                     queue[tail]=to;  
50                     vis[to]=1;  
51                 }  
52             }  
53         }  
54         vis[node]=0;  
55     }while(head!=tail);  
56     printf("%d\n",dis[maxx]);  
57 }