zoj 1508 Intervals (差分约束)

Intervals

Time Limit: 10 Seconds      Memory Limit: 32768 KB

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
",-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
",d[0]);
66     }
67     return 0;
68 }
View Code
原文地址:https://www.cnblogs.com/GO-NO-1/p/3440954.html