【HDOJ1384】【差分约束+SPFA】
http://acm.hdu.edu.cn/showproblem.php?pid=1384
Intervals
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 4638 Accepted Submission(s): 1765
Problem Description
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
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.
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
题目大意:给若干个区间,并且每个区间给定一个数C,表示集合S至少含有这个区间内C个整数,求满足要求的S的最小元素数
题目分析:典型的差分约束题目,即能根据题设条件列出若干不等式,并且所求问题中含有最小【或最大,最多,最少】字眼。都可以列出不等式,然后转化为最短路或者最长路。
本题要求区间【LI,RI】内含有CI个整数,即可令S【I】表示最终集合S在【0,I】区间内含有的整数,则本题要求即可化为S【RI】-S【LI-1】>= CI【条件不等式一】
又因为S【I】-S【I-1】>= 0 && S【I】-S【I-1】<= 1【条件不等式二、三】
题目所求最小元素数ANS 即S【Rmax】-s【Lmin-1】>= ANS 【所求不等式】
由所求不等式确定所求最长路还是最短路,从而据此再根据条件不等式可以建图,SPFA跑一遍即可。
【PS:边的结构体数组一定要开大一点,不然会TLE到怀疑人生...】
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 #include<queue> 6 using namespace std; 7 const int INF=100005; 8 struct edge{ 9 int to; 10 int len; 11 int next; 12 }EDGE[200005]; 13 queue<int>pq; 14 int edge_cnt=0,dist[50006],stk[50006],head[50006],n; 15 void add(int x,int y,int z) 16 { 17 EDGE[edge_cnt].to=y; 18 EDGE[edge_cnt].next=head[x]; 19 EDGE[edge_cnt].len=z; 20 head[x]=edge_cnt++; 21 } 22 void spfa() 23 { 24 while(!pq.empty()) 25 { 26 int qwq=pq.front();pq.pop(); 27 stk[qwq]=0; 28 for(int i = head[qwq] ; i != -1 ; i = EDGE[i].next) 29 { 30 int v=EDGE[i].to; 31 if(dist[v]<dist[qwq]+EDGE[i].len) 32 { 33 dist[v]=dist[qwq]+EDGE[i].len; 34 if(!stk[v]){ 35 stk[v]=1; 36 pq.push(v); 37 } 38 } 39 } 40 } 41 } 42 int main() 43 { 44 while(scanf("%d",&n)==1) 45 { 46 edge_cnt=0; 47 int mmin=500000; 48 int mmax=-1; 49 memset(dist,-1,sizeof(dist)); 50 memset(stk,0,sizeof(stk)); 51 memset(head,-1,sizeof(head)); 52 while(!pq.empty())pq.pop(); 53 while(n--) 54 { 55 int a,b,c; 56 scanf("%d%d%d",&a,&b,&c); 57 if(a) 58 add(a-1,b,c); 59 else 60 { 61 add(50005,b,c); 62 } 63 mmax=max(b,mmax); 64 mmin=min(a,mmin); 65 } 66 if(mmin==0) 67 { 68 dist[50005]=0; 69 add(50005,0,0); 70 add(0,50005,-1); 71 mmin=1; 72 stk[50005]=1; 73 pq.push(50005); 74 } 75 else 76 { 77 stk[mmin-1]=1; 78 pq.push(mmin-1); 79 dist[mmin-1]=0; 80 } 81 for(int i = mmin-1;i<mmax;i++) 82 { 83 add(i+1,i,-1); 84 add(i,i+1,0); 85 } 86 spfa(); 87 printf("%d\n",dist[mmax]); 88 } 89 return 0; 90 }