题目链接:poj 3281
题意:
有N头牛,F种食物可以制作,D种饮料可以制作
然后每行代表一头牛的喜好,开头两个数fi,di表示这头牛喜欢fi种食物,di种饮料,接下来fi个数表示喜欢的食物编号,di个数表示喜欢的饮料的编号
现在主人使用最优决策制作出F种食物和D种饮料,问怎么喂才能使尽可能多的牛喂饱(喂饱=一份食物一份饮料,且一头牛最多消耗一份食物和一份饮料)
输出最多喂饱的牛数。
题解:上个图就了解了,图文出处https://blog.csdn.net/ly59782/article/details/52848317
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
#define INF 0x3f3f3f3f
const int maxn=500;
int N,F,D;
int c[maxn][maxn],dep[maxn];
int bfs(int s,int t)
{
queue<int > q;
while(!q.empty()) q.pop();
memset(dep,-1,sizeof(dep));
dep[s]=0;
q.push(s);
while(!q.empty())
{
int u=q.front();
q.pop();
for(int v=1;v<=t;v++)
{
if(c[u][v]>0&&dep[v]==-1){
dep[v]=dep[u]+1;
q.push(v);
}
}
}
return dep[t]!=-1;
}
int dfs(int u,int mi,int t)
{
if(u==t) return mi;
int tmp;
for(int v=1;v<=t;v++)
{
if(c[u][v]>0&&dep[v]==dep[u]+1&&(tmp=dfs(v,min(mi,c[u][v]),t))){
c[u][v]-=tmp;
c[v][u]+=tmp;
return tmp;
}
}
return 0;
}
int dinic(int start,int ends)
{
int ans=0,tmp;
while(bfs(start,ends))
{
while(1){
tmp=dfs(start,INF,ends);
if(tmp==0) break;
ans+=tmp;
}
}
return ans;
}
int main()
{
while(~scanf("%d%d%d",&N,&F,&D))
{
memset(c,0,sizeof(c));
int start=1,ends=1+F+2*N+D+1;
for(int i=2;i<=F+1;i++) ///建立源点到食物的边
c[1][i]=1;
for(int i=1+F+1;i<=1+F+N;i++) ///建立牛与牛之间的边
c[i][i+N]=1;
for(int i=1+F+2*N+1;i<=1+F+2*N+D;i++) ///建立饮料到终点的边
c[i][ends]=1;
for(int i=1;i<=N;i++)
{
int food,drink;
scanf("%d%d",&food,&drink);
int item;
while(food--)
{
scanf("%d",&item);
c[item+1][1+F+i]=1; ///建立食物与牛之间的边
}
while(drink--)
{
scanf("%d",&item);
c[1+F+N+i][1+F+2*N+item]=1; ///建立牛与饮料之间的边
}
}
printf("%d\n",dinic(start,ends));
}
return 0;
}