poj1201/zoj1508/hdu1384 Intervals(差分约束)
转载请注明出处: http://www.cnblogs.com/fraud/ ——by fraud
You are given n closed, integer intervals [ai, bi] and n integers c1, ..., cn.
Write a program that:
> reads the number of intervals, their endpoints 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.
Input
The first line of the input contains an integer n (1 <= n <= 50 000) - 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 <= 50 000 and 1 <= ci <= bi
- ai + 1.
Process to the end of file.
Output
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.
Sample Input
5
3 7 3
8 10 3
6 8 1
1 3 1
10 11 1
Sample Output
6
题意:
对于一个序列,有n个描述,[ai,bi,ci]分别表示在区间[ai,bi]上,至少有ci个数属于该序列。输出满足这n个条件的最短的序列(即包含的数字个数最少)
分析:
设s[i]表示从0到i中有s[i]个数属于这个序列。
那么,对于每个描述,都可以得到一个方程s[bi]-s[ai-1]>=ci
同时由于每个数至多取一次,那么有s[i]-s[i-1]<=1,即s[i-1]-s[i]>=-1;
另外还有s[i]-s[i-1]>=0;
由这三个方程组建图,利用最长路即可求出。
1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <cstdlib> 5 #include <algorithm> 6 #include <queue> 7 using namespace std; 8 typedef long long ll; 9 typedef pair<int,int> PII; 10 #define MAXN 50010 11 #define REP(A,X) for(int A=0;A<X;A++) 12 #define INF 0x7fffffff 13 #define CLR(A,X) memset(A,X,sizeof(A)) 14 struct node { 15 int v,d,next; 16 }edge[3*MAXN]; 17 int head[MAXN]; 18 int e=0; 19 void init() 20 { 21 REP(i,MAXN)head[i]=-1; 22 } 23 void add_edge(int u,int v,int d) 24 { 25 edge[e].v=v; 26 edge[e].d=d; 27 edge[e].next=head[u]; 28 head[u]=e; 29 e++; 30 } 31 bool vis[MAXN]; 32 int dis[MAXN]; 33 void spfa(int s){ 34 CLR(vis,0); 35 REP(i,MAXN)dis[i]=i==s?0:INF; 36 queue<int>q; 37 q.push(s); 38 vis[s]=1; 39 while(!q.empty()) 40 { 41 int x=q.front(); 42 q.pop(); 43 int t=head[x]; 44 while(t!=-1) 45 { 46 int y=edge[t].v; 47 int d=edge[t].d; 48 t=edge[t].next; 49 if(dis[y]>dis[x]+d) 50 { 51 dis[y]=dis[x]+d; 52 if(vis[y])continue; 53 vis[y]=1; 54 q.push(y); 55 } 56 } 57 vis[x]=0; 58 } 59 } 60 int main() 61 { 62 ios::sync_with_stdio(false); 63 int n; 64 int u,v,d; 65 int ans=0; 66 int maxn=0; 67 int minn=MAXN; 68 while(scanf("%d",&n)!= EOF&&n) 69 { 70 e=0; 71 init(); 72 REP(i,n) 73 { 74 scanf("%d%d%d",&u,&v,&d); 75 add_edge(u,v+1,-d); 76 maxn=max(maxn,v+1); 77 minn=min(u,minn); 78 } 79 for(int i=minn;i<maxn;i++){ 80 add_edge(i+1,i,1); 81 add_edge(i,i+1,0); 82 } 83 spfa(minn); 84 cout<<-dis[maxn]<<endl; 85 } 86 return 0; 87 }