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
题意:对于每个区间[a,b]至少要有c个元素,问集合里元素的最小个数。
解析:差分约束,用Ti表示区间[0,i-1]有多少个元素在里面,则满足下面的条件
Tb+1-Ta>=c
0<=Ti+1-Ti<=1
则建边(a,b+1,c),(i,i+1,0),(i+1,i,-1) 然后用spfa求得答案。注意这题用vector可能会超时。
代码
#include<cstdio> #include<cstring> #include<string> #include<iostream> #include<sstream> #include<algorithm> #include<utility> #include<vector> #include<set> #include<map> #include<queue> #include<cmath> #include<iterator> #include<stack> using namespace std; const int INF=1e9+7; const double eps=1e-7; const int maxn=50005; int N; struct edge { int u,v,w,next; edge(int u=0,int v=0,int w=0):u(u),v(v),w(w){next=-1; } }E[maxn*3]; int head[maxn],dist[maxn]; bool inq[maxn]; queue<int> que; int spfa(int be,int en) { for(int i=be;i<=en;i++) dist[i]=-INF; dist[be]=0; memset(inq,false,sizeof(inq)); while(!que.empty()) que.pop(); que.push(be); while(!que.empty()) { int u=que.front(); que.pop(); inq[u]=false; for(int i=head[u];i!=-1;i=E[i].next) { int v=E[i].v,w=E[i].w; if(dist[v]<dist[u]+w) //更新 { dist[v]=dist[u]+w; if(!inq[v]){ inq[v]=true; que.push(v); } } } } return dist[en]; } int main() { while(scanf("%d",&N)!=EOF) { memset(head,-1,sizeof(head)); int u,v,w,cnt=0; int minv=INF,maxv=-INF; for(int i=0;i<N;i++) { scanf("%d%d%d",&u,&v,&w); //建边(u,v+1,w); v++; E[++cnt]=edge(u,v,w); E[cnt].next=head[u]; head[u]=cnt; minv=min(minv,u); maxv=max(maxv,v); } for(int i=minv;i<maxv;i++) { E[++cnt]=edge(i,i+1,0); //建边(i,i+1,0) E[cnt].next=head[i]; head[i]=cnt; E[++cnt]=edge(i+1,i,-1); //建边(i+1,i,-1) E[cnt].next=head[i+1]; head[i+1]=cnt; } printf("%d ",spfa(minv,maxv)); } return 0; }