zoj 1508 Intervals (差分约束)
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
Source: Southwestern Europe 2002
1 //2013-11-25 09:45:31 Accepted 1508 C++ 2120 2124 2 /* 3 4 题意: 5 有一个序列,题目用n个整数组合 [ai,bi,ci]来描述它,[ai,bi,ci]表示在该 6 序列中处于[ai,bi]这个区间的整数至少有ci个。如果存在这样的序列,请求出满足 7 题目要求的最短的序列长度是多少。如果不存在则输出 -1。 8 9 差分约束: 10 第一题差分约束,感觉还好,基本看过资料的应该都可以做。 11 难点在于构图部分,构好图后直接求其单源最短路径。 12 构图就是要满足 13 1)S(bi) - S(a(i-1))>=Ci 14 2)Si - S(i-1)>=0 15 3)S(i-1) - Si>=-1 16 17 即 map[bi][a(i-1)]=-ci 18 map[i][i-1]=0 19 map[i-1][i]=1 20 21 然后在采用最短路算法求点n到点0的最短路,值再取反即为解 22 存在负权环时不存在 23 24 */ 25 #include<stdio.h> 26 #include<string.h> 27 #define N 50005 28 #define inf 0x7ffffff 29 using namespace std; 30 struct node{ 31 int u,v,w; 32 }edge[3*N]; 33 int n,edgenum,m; 34 int d[N]; 35 int Max(int a,int b) 36 { 37 return a>b?a:b; 38 } 39 void addedge(int u,int v,int w) 40 { 41 edge[edgenum].u=u; 42 edge[edgenum].v=v; 43 edge[edgenum++].w=w; 44 } 45 bool bellman_ford() 46 { 47 bool flag; 48 for(int i=0;i<=m;i++) d[i]=inf; 49 d[m]=0; 50 for(int i=1;i<m;i++){ 51 flag=false; 52 for(int j=0;j<edgenum;j++){ 53 if(d[edge[j].u]!=inf && d[edge[j].v]>d[edge[j].u]+edge[j].w){ 54 flag=true; 55 d[edge[j].v]=d[edge[j].u]+edge[j].w; 56 } 57 } 58 if(!flag) break; 59 } 60 for(int i=0;i<edgenum;i++) 61 if(d[edge[i].u]!=inf && d[edge[i].v]>d[edge[i].u]+edge[i].w) 62 return false; 63 return true; 64 } 65 int main(void) 66 { 67 int a,b,c; 68 while(scanf("%d",&n)!=EOF) 69 { 70 edgenum=0; 71 m=0; 72 for(int i=0;i<n;i++){ 73 scanf("%d%d%d",&a,&b,&c); 74 addedge(b,a-1,-c); 75 m=Max(m,Max(a,b)); 76 } 77 for(int i=0;i<m;i++){ 78 addedge(i,i+1,1); 79 addedge(i+1,i,0); 80 } 81 if(!bellman_ford()) puts("-1"); 82 else printf("%d\n",-d[0]); 83 } 84 return 0; 85 }
贴一下SPFA的解法:
1 //2013-11-25 22:05:24 Accepted 1508 C++ 130 5444 2 #include<iostream> 3 #include<vector> 4 #include<queue> 5 #include<stdio.h> 6 #include<string.h> 7 #define N 50005 8 #define inf 0x7ffffff 9 using namespace std; 10 struct node{ 11 int v,w; 12 node(int a,int b){ 13 v=a;w=b; 14 } 15 }; 16 vector<node>V[N]; 17 int d[N],vis[N],in[N]; 18 int n,m; 19 int spfa() 20 { 21 memset(vis,0,sizeof(vis)); 22 memset(in,0,sizeof(in)); 23 for(int i=0;i<=m;i++) d[i]=-inf; 24 queue<int>Q; 25 Q.push(m); 26 d[m]=0; 27 while(!Q.empty()){ 28 int u=Q.front(); 29 Q.pop(); 30 if(in[u]>m) return 0; 31 vis[u]=0; 32 int n0=V[u].size(); 33 for(int i=0;i<n0;i++){ 34 int v=V[u][i].v; 35 int w=V[u][i].w; 36 if(d[v]<d[u]+w){ 37 d[v]=d[u]+w; 38 if(!vis[v]){ 39 in[v]++; 40 Q.push(v); 41 vis[v]=1; 42 } 43 } 44 } 45 } 46 return 1; 47 } 48 int main(void) 49 { 50 int a,b,c; 51 while(scanf("%d",&n)!=EOF) 52 { 53 m=0; 54 for(int i=0;i<N;i++) V[i].clear(); 55 for(int i=0;i<n;i++){ 56 scanf("%d%d%d",&a,&b,&c); 57 m=max(m,max(a,b)); 58 V[b].push_back(node(a-1,c)); 59 } 60 for(int i=0;i<m;i++){ 61 V[i].push_back(node(i+1,-1)); 62 V[i+1].push_back(node(i,0)); 63 } 64 if(!spfa()) puts("impossible"); 65 else printf("%d\n",d[0]); 66 } 67 return 0; 68 }