吃饭网络流
Posted hello-tomorrow
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了吃饭网络流相关的知识,希望对你有一定的参考价值。
题目大意:
有n头牛,每头牛有自己喜欢的食物和饮料,每种食物或饮料只有一个。求最多能让多少头牛吃到食物并喝到饮料。
思路:
很明显的最大流题目。这道题匈牙利会超时,正解是DinicDinic。
这道题最难的也就是考点是建图。很容易想到这样的建法(权值均为1):
但是这样的话,就有可能一头牛吃多个食物及饮料,例如上图中牛1可以既吃食物1,饮料2组成的套餐,又可以吃食物2,饮料d组成的套餐。
所以,这里就要拆点。将一头牛拆成两头,中间连一条权值为1的线,就可以保证不会有一头牛吃多组套餐的情况。
代码:
#include <cstdio> #include <iostream> #include <cstring> #include <queue> #define Inf 0x7f #define INF 2147483647 using namespace std; int n,f,d,s,t,ans,sum,num,fnum,dnum,x,k,head[5000001],dep[5000001]; struct edge { int c,to,next; }e[5000001]; void add(int from,int to,int c) { k++; e[k].to=to; e[k].c=c; e[k].next=head[from]; head[from]=k; } bool bfs() //分层 { memset(dep,Inf,sizeof(dep)); queue<int> q; q.push(s); dep[s]=0; while (q.size()) { int u=q.front(); q.pop(); for (int i=head[u];i;i=e[i].next) { int v=e[i].to; if (dep[v]>dep[u]+1&&e[i].c) { dep[v]=dep[u]+1; q.push(v); } } } return (dep[t]<Inf); } int dfs(int u,int low) { int lows=0; if (u==t) return low; for (int i=head[u];i;i=e[i].next) { int v=e[i].to; if (dep[v]==dep[u]+1&&e[i].c) { lows=dfs(v,min(low,e[i].c)); //继续找增广路 if (!lows) continue; e[i].c-=lows; //正向边 e[(i+1)^1-1].c+=lows; //反向边 return lows; } } return 0; } int main() { //建图时牛a编号为1~n,牛b编号为n+1~2n,食物编号为2n+1~2n+f,饮料编号为2n+f+1~2n+f+d scanf("%d%d%d",&n,&f,&d); s=0; t=n+n+f+d+1; for (int i=1;i<=n;i++) { scanf("%d%d",&fnum,&dnum); for (int j=1;j<=fnum;j++) //食物连向牛a { scanf("%d",&x); add(n+n+x,i,1); add(i,n+n+x,0); } for (int j=1;j<=dnum;j++) //牛b连向饮料 { scanf("%d",&x); add(n+i,n+n+f+x,1); add(n+n+f+x,n+i,0); } } for (int i=1;i<=n;i++) //牛a连向牛b { add(i,n+i,1); add(n+i,i,0); } for (int i=1;i<=f;i++) //S连向食物 { add(s,n+n+i,1); add(n+n+i,s,0); } for (int i=1;i<=d;i++) //饮料连向T { add(n+n+f+i,t,1); add(t,n+n+f+i,0); } while (bfs()) { while (sum=dfs(s,INF)) ans+=sum; } printf("%d ",ans); return 0; }
以上是关于吃饭网络流的主要内容,如果未能解决你的问题,请参考以下文章
[Luogu P2891/POJ 3281/USACO07OPEN ]吃饭Dining
P2891 [USACO07OPEN]吃饭Dining(最大流+拆点)
java内存流:java.io.ByteArrayInputStreamjava.io.ByteArrayOutputStreamjava.io.CharArrayReaderjava.io(代码片段