POJ 1201-Intervals

来源:互联网 发布:京都 和服 知乎 编辑:程序博客网 时间:2024/05/27 09:47

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 end points 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 <= 50000) -- 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 <= 50000 and 1 <= ci <= bi - ai+1.

题目大意:

给出n个闭区间[ai,bi],每个区间对应一个ci,表示集合Z在区间[ai,bi]内至少有ci个相同元素,问集合Z至少有几个元素。
每个测试点有多组输入数据
每组第一行为n (1 <= n <= 50000)。接下来n行,每行给出一组ai,bi,ci。(0 <= ai <= bi <= 50000,1 <= ci <= bi - ai+1.

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.
要求输出集合Z中最少有几个元素,题目保证有解。

Sample Input

53 7 38 10 36 8 11 3 110 11 1

Sample Output

6

题解

差分约束系统。最近恶补知识面,看清北学堂2013年noip的视频时,想起来要做点题练练了。

首先从视频上对差分约束系统大致的认识是:将题目给出不等式作为最短(长)路的限制条件,跑最短(长)路,当有负环时无解。

可是这道题没给我们不等式,但有“最小”这个条件,所以用Si表示区间[0,i]区间内至少有多少个元素的话,那么Sbi - Sai >= ci。可转换为Sbi>= Sai+ci,这可作为跑最长路的限制条件了。可是这样50000个点只连了少量边,可能跑不出我们想要的最短路。为了保险,还有一个式子:0<=Si - Si-1<=1,这样就能跑最长路了。因为题目保证有解,所以不用判负环。

#include<cstdio>#include<cstring>#include<cstdlib>#include<iostream>#include<cmath>#include<algorithm>#define inf 1<<30using namespace std;int n,head[50005],zz,S,T;struct bian{int to,nx,v;} e[200002];int dis[50005],pd[50005],q[50005];void insert(int x,int y,int z){zz++; e[zz].to=y; e[zz].v=z; e[zz].nx=head[x]; head[x]=zz;}void init(){memset(head,0,sizeof(head));zz=0; S=inf; T=-inf;int i,a,b,c;for(i=1;i<=n;i++)   {scanf("%d%d%d",&a,&b,&c);    insert(a,b+1,c);//因为a>=0,为了让a-1不超界,所以将所有点向正方向平移一位     S=min(S,a); T=max(T,b+1);   }for(i=S;i<T;i++)   {insert(i,i+1,0); insert(i+1,i,-1);}}void spfa(){int t=0,w=1,i,p;for(i=S;i<=T;i++) {dis[i]=-inf; pd[i]=0;}dis[S]=0; pd[S]=1; q[t]=S;while(t!=w)   {p=q[t];    t=(t+1)%50003;    for(i=head[p];i;i=e[i].nx)       {if(dis[e[i].to]<dis[p]+e[i].v)      {dis[e[i].to]=dis[p]+e[i].v;   if(!pd[e[i].to])      {pd[e[i].to]=1; q[w]=e[i].to; w=(w+1)%50003;}  }   }pd[p]=0;   } printf("%d\n",dis[T]);}int main(){while(scanf("%d",&n)!=EOF)   {init(); spfa();}return 0;} 


 

0 0
原创粉丝点击