您的位置:首页 > 运维架构

bzoj 1711: [Usaco2007 Open]Dining吃饭

2017-12-23 21:46 344 查看
http://www.lydsy.com/JudgeOnline/problem.php?id=1711

源点连向食物流量为1,食物连向人流量为1,把人拆点限流,人连向饮料流量为1

饮料连向汇点流量为1,然后,最大流

#include<cstdio>
#include<queue>
#include<cstring>
#include<algorithm>
std::queue<int>que;
#define INF 0x7fffffff
const int maxn = 30007;
inline int read() {
int x=0;
char c=getchar();
while(c<'0'||c>'9')c=getchar();
while(c<='9'&&c>='0')x=x*10+c-'0',c=getchar();
return x;
}
int n,f,d,S,T,src,decc;
struct node{
int v,next,flow;
}edge[maxn];int head[maxn],num=1,cur[maxn],lev[maxn];
void add_edge(int u,int v,int w) {
edge[++num].v=v;edge[num].next=head[u];head[u]=num;
edge[num].flow=w;
}
bool bfs() {
while(!que.empty()) que.pop();
std::memset(lev,-1,sizeof lev);
memcpy(cur,head,sizeof head);
lev[src]=0;
que.push(src);int now;
while(!que.empty()) {
now=que.front();que.pop();
for(int i=head[now];i;i=edge[i].next) {
int v=edge[i].v;
if(lev[v]==-1&&edge[i].flow>0) {
lev[v]=lev[now]+1;
if(v==decc)return true;
que.push(v);
}
}
}
return false;
}
int dfs(int now,int flow) {
if(now==decc)return flow;
int rest=0,delta;
for(int &i=cur[now];i;i=edge[i].next) {
int v=edge[i].v;
if(lev[v]==lev[now]+1&&edge[i].flow>0) {
delta=dfs(v,std::min(flow-rest,edge[i].flow));
if(delta) {
edge[i].flow-=delta;
edge[i^1].flow+=delta;
rest+=delta;if(rest==flow)break;
}
}
}
if(rest==flow)lev[now]=-1;//满流
return rest;
}
int Dinic() {
int ans=0;
while(bfs())
ans+=dfs(src,INF);
return ans;
}
inline void add(int a,int b,int flow) {
add_edge(a,b,flow);add_edge(b,a,0);
}
int main() {
n=read(),f=read(),d=read();
src=0;decc=f+n+n+d+1;
for(int a,b,po,i=1;i<=n;++i) {
a=read(),b=read();
for(int j=1;j<=a;++j) po=read(),add(po,f+i,1);
add(f+i,f+n+i,1);
for(int j=1;j<=b;++j) po=read(),add(f+n+i,f+n+n+po,1);
}
for(int i=1;i<=f;++i)add(src,i,1);
for(int i=f+n+n+1;i<=f+n+n+d;++i)add(i,decc,INF);
printf("%d\n",Dinic());
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: