题的地址:http://poj.org/problem?id=3281
题目大意:有f种食物,d种饮料,n头奶牛,只能吃某种食物和饮料(而且只能吃特定的一份),一种食物被一头,牛吃了之后,其余牛就不能吃了,第一行有n,f,d三个整数,接着每一行代表第几头牛,前面两个整数是fi与di(食物与饮料的种类数量),接着是食物的种类与饮料的种类,要求输出最多分配能够满足的牛的数量
解题思路:很明显 此题可以用到网络流中的求最大流的知识。只是想想该怎么建图,建图是关键,建完图直接套网络流求最大流的模板即可AC
图大致是这样的,0表示源点,2*n+f+d+1表示汇点
由源点指向食物,再由食物指向牛,牛再指向对应的饮料,饮料再指向汇点 中间牛与牛再相连
//Memory: 304K
//Time: 0MS
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <map>
#include <cmath>
#include <queue>
#include <string>
#include <vector>
#include <set>
using namespace std;
#define ll long long
#define sc(x) scanf("%d",&x)
#define dsc(x,y) scanf("%d%d",&x,&y)
#define sssc(x) scanf("%s",s)
#define sdsc(x,y) scanf("%s %s",x,y)
#define ssc(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define pr(x) printf("%d\n",x)
#define FOR(i,n,o) for(int i=o;i<=n;i++)
#define lcr(a,b) memset(a,b,sizeof(a))
#define Inf 1<<29
const int maxn=101;
const int maxm=maxn*maxn;
int n,f,s,t,d,m,e,head[maxn*maxn],vis[maxn*maxn];
queue <int> p;
struct node
{
int v;
int c;
int next;
}q[maxn*maxn];
void add(int u,int v,int c)
{
q[e].v=v;q[e].c=c;q[e].next=head[u];head[u]=e++;
q[e].v=u;q[e].c=0;q[e].next=head[v];head[v]=e++;
}
int bfs(int s,int t)
{
lcr(vis,0);
while(!p.empty())
p.pop();
vis[s]=1;
p.push(s);
while(!p.empty())
{
int u=p.front();
p.pop();
for(int i=head[u];~i;i=q[i].next)
{
int v=q[i].v;
if(!vis[v]&&q[i].c)
{
vis[v]=vis[u]+1;
p.push(v);
if(v==t)
return vis[t];
}
}
}
return vis[t];
}
int dfs(int u,int maxf)
{
int flow=0;
if(u==t||maxf==0)
{
return maxf;
}
for(int i=head[u],f;~i;i=q[i].next)
{
int v=q[i].v;
if(vis[v]==vis[u]+1&&q[i].c&&(f=dfs(v,min(q[i].c,maxf))))
{
q[i].c-=f;
q[i^1].c+=f;
maxf-=f;
flow+=f;
if(!maxf)
break;
}
}
if(!flow)
vis[u]=0;
return flow;
}
int maxif(int s,int t)
{
int maxid=0;
while(bfs(s,t))
{
while(1)
{
int f=dfs(s,Inf);
if(f==0)
break;
maxid+=f;
}
}
return maxid;
}
int main()
{
while(~ssc(n,f,d))
{
e=0;
lcr(head,-1);
s=0;//源点
t=1+n*2+f+d;//汇点
FOR(i,f,1)
add(s,i,1);//连接汇点与食物
FOR(i,d,1)
add(f+2*n+i,t,1);//连接饮料与汇点
FOR(i,n,1)
add(f+i,f+n+i,1);//连接中间的牛与牛
FOR(i,n,1)
{
int a,b;
dsc(a,b);
FOR(j,a,1)
{
int tt;
sc(tt);
add(tt,i+f,1);//连接食物和牛
}
FOR(j,b,1)
{
int tt;
sc(tt);
add(f+n+i,f+2*n+tt,1);//连接牛和饮料
}
}
pr(maxif(s,t));
}
return 0;
}
END!!!!!!!!!!!!!!!!!!!!!!