您的位置:首页 > 其它

hdu 2883 kebab

2012-09-15 10:48 225 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2883

题目大意:不好说

题目思路:很巧的一道题目,附出题人的解题报告:
将所有的到达时间和结束时间按升序排序,得到 x <= 2n-1 个时间区间。建立网络流模型:s为源,t为汇,每个顾客i作为一个结点并连边(s, i, ni*ti),每个区间j作为一个结点并连边(j, t, (ej-sj)*M),其中sj, ej分别表示区间j的起始时间和终止时间。对任意顾客i和区间j,若 [sj, ej] 完全包含在 [si, ei] 之中,则连边(i, j, INF)。若最大流等于 ∑ni*ti 则是 Yes,否则是 No。

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<string>
#include<queue>
#include<algorithm>
#include<vector>
#include<stack>
#include<list>
#include<iostream>
#include<map>
using namespace std;
#define inf 0x3f3f3f3f
#define Max 800
int max(int a,int b)
{
return a>b?a:b;
}
int min(int a,int b)
{
return a<b?a:b;
}
int dis[Max],gap[Max],pre[Max],cur[Max],p[Max];
int in[Max],out[Max];
int n,m,s,t,eid;
struct node
{
int to,next,c;
}e[40400];
void addedge(int u,int v,int c)
{
e[eid].to=v;
e[eid].c=c;
e[eid].next=p[u];
p[u]=eid++;
}
int  ISAP(int st,int ed,int n)   ///起点,终点,顶点数
{
memset(dis, 0, sizeof(dis));
memset(gap, 0, sizeof(gap));  gap[0]=n;
memcpy(cur, p, sizeof(p));      ///memcpy!
int  i,flag,v,u=pre[st]=st,maxflow=0,aug=inf; //puts("akk");
while(dis[st] < n)
{
for(flag=0,i=cur[u];i!=-1; i=e[i].next)  /// cur[u]
if(e[i].c&& dis[u] == dis[e[i].to]+1)
{
flag = 1;

break;
}
if(flag)
{
if(aug > e[i].c)
aug = e[i].c;
v = e[i].to;
pre[v] = u;
cur[u] = i;
u = v;
if(u == ed)
{
for(u=pre[u]; 1;u=pre[u])    ///notice!
{
e[cur[u]].c -= aug;
e[cur[u]^1].c += aug;
if(u==st) break;
}
maxflow += aug;
aug = inf;
}
}
else
{
int minx = n;
for(i=p[u]; i!=-1; i=e[i].next)
if(e[i].c&& dis[e[i].to]<minx)
{
minx = dis[e[i].to];
cur[u] = i;
}
if(--gap[dis[u]] == 0)
break;
dis[u] = minx+1;
gap[dis[u]]++;
u = pre[u];
}
}
return maxflow;
}
int st[300],ed[300];
int a[600],need[300];
int src,dest;
int main()
{
int m,n,t,count=1,sum,cnt;
int u,v,i,j,k,x,y,tp,ni,ti;
while(scanf("%d%d",&n,&m)!=EOF)
{
memset(p,-1,sizeof(p));
eid=0;
cnt=0;
sum=0;
for(i=0;i<n;i++)
{
scanf("%d%d%d%d",&st[i],&ni,&ed[i],&ti);
a[cnt++]=st[i];
a[cnt++]=ed[i];
need[i]=ni*ti;
sum+=need[i];
}
sort(a,a+cnt);
j=1;
for(i=1;i<cnt;i++)
{
if(a[i]>a[i-1])
a[j++]=a[i];
}
cnt=j;
src=n+cnt-1;
dest=src+1;
for(i=0;i<cnt-1;i++)
{
addedge(src,n+i,m*(a[i+1]-a[i]));
addedge(n+i,src,0);
for(j=0;j<n;j++)
{
if(st[j]<=a[i]&&ed[j]>=a[i+1])
{
addedge(n+i,j,inf);
addedge(j,n+i,0);
}
}
}
for(i=0;i<n;i++)
{
addedge(i,dest,need[i]);
addedge(dest,i,0);
}
if(ISAP(src,dest,dest+1)==sum)
puts("Yes");
else
puts("No");
}
}

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