参考https://blog.youkuaiyun.com/wangjian8006/article/details/7933079
题意:有F种食物,D种饮料,N头奶牛,每头牛只能吃某种食物和饮料(而且只能吃特定的一份),一种食物被一头牛吃了之后,其余牛就不能吃了
第一行有N,F,D三个整数
下面N行代表第i头牛,前面两个整数是Fi与Di(食物与饮料的种类数量),接着是食物的种类与饮料的种类
要求输出最多分配能够满足的牛的数量
解题思路:建图,有2*n+f+d+2个顶点
0表示源点,2*n+f+d+1表示汇点
由源点指向食物,再由食物指向牛,牛再指向对应的饮料,饮料再指向汇点
当然要使每一头牛都对应每一份食物与饮料,所以应该牛i指向牛i再指向饮料,全部是有向的边,而且权值全部为1。
在这里是1到f为食物点,f+1到f+2*n为牛点,f+2*n+1到f+2*n+d为饮料点
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <queue>
using namespace std;
#define inf 0x7fffffff
struct Edge{
int v,w,nxt;
}g[10001];
int head[10001];
int cnt;
void addEdge(int u,int v,int w){
g[cnt].v = v;
g[cnt].w = w;
g[cnt].nxt = head[u];
head[u] = cnt;
++ cnt;
}
int n,m,x,y,z;
int ans,flow;
int dis[10001];
queue<int> q;
int S,T;
void init(){
memset(head,-1,sizeof(head));
memset(g,0,sizeof(g));
cnt = 0;
memset(dis,-1,sizeof(dis));
while(!q.empty()) q.pop();
ans = 0;
}
int bfs(){
memset(dis,-1,sizeof(dis));
while(!q.empty()) q.pop();
dis[S] = 0;
q.push(S);
while(!q.empty()){
int u = q.front();
q.pop();
for(int i=head[u];i!=-1;i=g[i].nxt){
int v = g[i].v;
if(dis[v]==-1 && g[i].w > 0){
dis[v] = dis[u] + 1;
q.push(v);
}
}
}
return dis[T]!=-1;
}
int dfs(int u,int exp){
if(u==T) return exp;
int flow=0,tmp= 0;
for(int i=head[u];i!=-1;i=g[i].nxt){
int v = g[i].v;
if((dis[v] == (dis[u]+1)) && (g[i].w>0)){
tmp = dfs(v,min(exp,g[i].w));
if(!tmp) continue;
exp -= tmp;
flow += tmp;
g[i].w -= tmp;
g[i^1].w += tmp;
if(!exp) break;
}
}
return flow;
}
int main(){
int f,d,tmp;
while(~scanf("%d%d%d",&n,&f,&d)){
init();
S =0;T =2*n+f+d+1;
for(int i=1;i<=f;i++)
{
addEdge(0,i,1);
addEdge(i,0,0);
}
for(int i=1;i<=d;i++)
{
addEdge(2*n+f+i,T,1);
addEdge(T,2*n+f+i,0);
}
for(int i=1;i<=n;i++)
{
addEdge(f+i,f+n+i,1);
addEdge(f+i+n,f+i,0);
}
for(int i=1;i<=n;++i){
scanf("%d%d",&x,&y);
for(int j=1;j<=x;j++)
{
scanf("%d",&tmp);
addEdge(tmp,f+i,1);
addEdge(f+i,tmp,0);
}
for(int j=1;j<=y;j++)
{
scanf("%d",&tmp);
addEdge(f+n+i,f+2*n+tmp,1);
addEdge(f+2*n+tmp,f+n+i,0);
}
}
while(bfs()){
ans += dfs(S,inf);
}
printf("%d\n",ans);
}
}