题目链接点击打开链接
最大流题目多起点多聚点类型,要加一个最原始的起点和聚点。本题由于一个牛对应一种食物和水搭配,因此要添加牛x-->牛x的容量为1的路径,否则就会出现一牛对应多条路径的情况。至于点的标号。0是原始起点,1——f 表示food,f+1——2n表示牛,f+2n+1——f+2n+d表示drink f+2n+d+1 表示终点,一共f+2n+d+1 +1 个点。
AC代码
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<iomanip>
#include<algorithm>
#include<cmath>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<stack>
typedef long long ll;
#define pi acos(-1)
#define eps 1e-6;
using namespace std;
const int inf=1<<28;
const int maxn=405;
int mp[maxn][maxn],path[maxn],flow[maxn],sta,ed,n;
int bfs()
{
int i,tmp;
memset(path,-1,sizeof(path));
queue<int> q;
path[sta]=0,flow[sta]=inf;
q.push(sta);
while(!q.empty())
{
tmp=q.front();
q.pop();
if(tmp==ed) break;
for(i=1; i<=n; i++)
{
if(path[i]==-1 && i!=sta && mp[tmp][i])
{
flow[i]=min(mp[tmp][i],flow[tmp]);
path[i]=tmp;
q.push(i);
}
}
}
if(path[ed]==-1) return -1;
return flow[ed];
}
int EK()
{
int max_flow=0,step,now,pre;
while((step=bfs()) != -1)
{
max_flow+=step;
now=ed;
while(now!=sta)
{
pre=path[now];
mp[pre][now]-=step;
mp[now][pre]+=step;
now=pre;
}
}
return max_flow;
}
int main()
{
int f,d,i,ff,dd,food,drink;
while(~scanf("%d%d%d",&n,&f,&d))
{
memset(mp,0,sizeof(mp));
sta=0,ed=2*n+f+d+1;
for(i=1; i<=f; i++) mp[0][i] = 1; ///start to food
for(i=1; i<=d; i++) mp[2*n+f+i][ed] = 1; ///drink to end
for(i=1; i<=n; i++) mp[f+i][f+i+n] = 1; ///cow to cow
for(i=1; i<=n; i++)
{
scanf("%d%d",&ff,&dd);
while(ff--)
{
scanf("%d",&food);
mp[food][i+f] = 1;///drink to cow
}
while(dd--)
{
scanf("%d",&drink);
mp[n+f+i][2*n+f+drink] = 1;///cow to drink
}
}
n=ed+1;/// the count of point
printf("%d\n",EK());
}
return 0;
}