我的最大流的第二题,,,话说刚学网络流,,用了最常用的算法E_k算法还调试了一会,,,,杯具啊,,看了网上大牛们的解题报告,用的都是Dinci和ISPA,,,很是神奇啊,,看来是得学学了,,,这道题难在建图上,,,为了保证每种食物,和饮料只对应一头牛,用了拆点,,,建图顺序为源点-食物-牛-牛-饮料-汇点,,每个弧的容量为1,做完这题我明白了为什么最大二分匹配可以用网络流来做了,,嘎嘎,,,
#include<iostream>
#include<cstdio>
#include<limits.h>
#include<algorithm>
#include<queue>
#define M 405
#include<string.h>
using namespace std;
int map[M][M];
int N,F,D;
void E_k(int s,int t)
{ int flow[M][M],f[M],pre[M],flowmax=0;
queue<int> Q;
memset(flow,0,sizeof(flow));
while(1)
{ Q.push(s);
memset(f,0,sizeof(f));
f[s]=INT_MAX;
while(!Q.empty())
{ int u=Q.front();
Q.pop();
for(int i=s;i<=t;++i)
if(!f[i]&&map[u][i]>flow[u][i])
{ Q.push(i);
f[i]=min(f[u],map[u][i]-flow[u][i]);
pre[i]=u;
}
}
if(!f[t]) break;
for(int i=t;i!=s;i=pre[i])
{ flow[pre[i]][i]+=f[t];
flow[i][pre[i]]-=f[t];
}
flowmax+=f[t];
}
printf("%d\n",flowmax);
}
int main()
{ while(~scanf("%d%d%d",&N,&F,&D))
{ memset(map,0,sizeof(map));
int a,b;
for(int i=1;i<=N;++i)
{ scanf("%d%d",&a,&b);
map[i][N+i]=1;
while(a--)
{ int c;
scanf("%d",&c);
map[2*N+c][i]=1;
}
while(b--)
{ int c;
scanf("%d",&c);
map[N+i][2*N+F+c]=1;
}
}
for(int i=2*N+1;i<=2*N+F;++i)
map[0][i]=1;
for(int i=2*N+F+1;i<=2*N+F+D;++i)
map[i][2*N+F+D+1]=1;
E_k(0,2*N+F+D+1);
}return 0;
}