您的位置:首页 > 理论基础 > 计算机网络

hdu 2883 网络流

2014-04-22 10:59 197 查看
这题和3572很相似 关键就是区间变得难找了 如何表示烤肉可以在一段时间内被烤呢?

这里用到了离散化,说白了 就是记录区间的端点,然后如果存在时间区间包含在该人的出现和离开区间之内

说明此时的肉是可以被烤的

#include<queue>
#include<stdio.h>
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
#define maxn 11111
#define inf 11111111
struct edge{int to,cap,rev;};
vector<edge>g[maxn];
int lv[maxn],iter[maxn];
void add(int u,int v,int w){
g[u].push_back((edge){v,w,(int)g[v].size()});
g[v].push_back((edge){u,0,(int)g[u].size()-1});
}
void bfs(int s)
{
memset(lv,-1,sizeof lv);
queue<int>q;
q.push(s);
lv[s]=0;

int v;
while(!q.empty())
{
v=q.front();
q.pop();
for(int i=0;i<g[v].size();++i)
{
if(lv[g[v][i].to]<0&&g[v][i].cap>0)
{
lv[g[v][i].to]=lv[v]+1;
q.push(g[v][i].to);
}
}
}
}
int dfs(int u,int v,int f)
{
if(u==v)return f;
for(int &i=iter[u];i<g[u].size();++i)
{
edge &e=g[u][i];
if(lv[u]<lv[e.to]&&e.cap>0)
{
int d=dfs(e.to,v,min(f,e.cap));
if(d>0)
{
e.cap-=d;
g[e.to][e.rev].cap+=d;
return d;
}
}
}
return 0;
}
int max_flow(int s,int t)
{
int flow=0;
for(;;)
{
memset(lv,-1,sizeof lv);
bfs(s);
if(lv[t]<0)return flow;
memset(iter,0,sizeof iter);
int f;
while((f=dfs(s,t,inf))>0){
flow+=f;
}
}
}
int main()
{
int n,m;
int sum;
int ti,ni;
int s[202],tol[404],e[202];
while(~scanf("%d%d",&n,&m))
{
sum=0;
int tot=0,st=0,ed;
for(int i=1;i<=n;++i)
{
scanf("%d%d%d%d",&s[i],&ni,&e[i],&ti);
sum+=ni*ti;
add(st,i,ni*ti);
tol[tot++]=s[i];
tol[tot++]=e[i];

}
sort(tol,tol+tot);
int c=0;
for(int i=1;i<tot;++i)
{
if(tol[c]!=tol[i])tol[++c]=tol[i];
}
ed=c+n+1;
for(int i=1;i<=c;++i)
{
int tmp=tol[i]-tol[i-1];
add(n+i,ed,tmp*m);
for(int j=1;j<=n;++j)
{
if(tol[i-1]>=s[j]&&tol[i]<=e[j])
{
add(j,i+n,inf);
}
}
}
int ans=max_flow(st,ed);
if(sum==ans)printf("Yes\n");
else printf("No\n");

for(int i=0;i<=ed;++i)g[i].clear();

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