您的位置:首页 > 其它

poj 1201 Intervals(差分约束求最长路)

2013-07-26 22:29 441 查看
[align=center]Intervals[/align]

TimeLimit:2000MSMemoryLimit:65536K
TotalSubmissions:19189Accepted:7216
Description
Youaregivennclosed,integerintervals[ai,bi]andnintegersc1,...,cn.

Writeaprogramthat:

readsthenumberofintervals,theirendpointsandintegersc1,...,cnfromthestandardinput,

computestheminimalsizeofasetZofintegerswhichhasatleastcicommonelementswithinterval[ai,bi],foreachi=1,2,...,n,

writestheanswertothestandardoutput.

Input
Thefirstlineoftheinputcontainsanintegern(1<=n<=50000)--thenumberofintervals.Thefollowingnlinesdescribetheintervals.The(i+1)-thlineoftheinputcontainsthreeintegersai,biandciseparatedbysingle
spacesandsuchthat0<=ai<=bi<=50000and1<=ci<=bi-ai+1.
Output
TheoutputcontainsexactlyoneintegerequaltotheminimalsizeofsetZsharingatleastcielementswithinterval[ai,bi],foreachi=1,2,...,n.
SampleInput
5
373
8103
681
131
10111

SampleOutput
6


题意:给出n个区间,每个区间给出一个数ci,求一个size最小的整数集合,使该集合落在每个区间的元素>=ci。

思路:设为区间[0,i]有sum[i]个数,则对于每个关系a,b,c,有sum[b+1]-sum[a]>=c。另外隐藏条件为0<=sum[i+1]-sum[i]<=1。要求最小值,则求最长路,对于(b+1)-a>=c,建一条边为a->b+1,边权为c。


AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<queue>
#include<vector>
#include<cmath>
#include<stack>
#include<map>

usingnamespacestd;

constintINF=100000000;
constintmaxn=50005;

structnode
{
intv,w,next;
}edge[maxn*3];
inthead[maxn],dis[maxn];
boolvis[maxn];
intnum,n,m,maxi,mini;
voidinit()
{
memset(head,-1,sizeof(head));
num=0;
}
voidadd(intu,intv,intw)
{
edge[num].v=v;
edge[num].w=w;
edge[num].next=head[u];
head[u]=num++;
}
intspfa()
{
queue<int>Q;
for(inti=mini;i<=maxi;i++)
dis[i]=-INF;
dis[mini]=0;
memset(vis,false,sizeof(vis));
vis[mini]=true;
Q.push(mini);
while(!Q.empty())
{
intx=Q.front();
Q.pop();
vis[x]=false;
for(inti=head[x];i!=-1;i=edge[i].next)
{
if(dis[edge[i].v]<dis[x]+edge[i].w)
{
dis[edge[i].v]=dis[x]+edge[i].w;
if(!vis[edge[i].v])
{
vis[edge[i].v]=true;
Q.push(edge[i].v);
}
}
}
}
returndis[maxi];
}
intmain()
{
inta,b,c;
while(scanf("%d",&n)!=EOF)
{
init();
maxi=0;
mini=INF;
while(n--)
{
scanf("%d%d%d",&a,&b,&c);
maxi=max(maxi,b+1);
mini=min(mini,a);
add(a,b+1,c);
}
for(inti=mini;i<maxi;i++)
{
add(i,i+1,0);
add(i+1,i,-1);
}
printf("%d\n",spfa());
}
return0;
}

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: