【POJ 3281】Dining 网络流

农夫为他的 N (1 ≤ N ≤ 100) 牛准备了 F (1 ≤ F ≤ 100)种食物和 D (1 ≤ D ≤ 100) 种饮料。每头牛都有各自喜欢的食物和饮料,而每种食物或饮料只能分配给一头牛。最多能有多少头牛可以同时得到喜欢的食物和饮料?

Input

第一行输入三个整数N, F, D

接下来n行,每行先输入两个整数 Fi 和 Di,分别表示编号为 i 的牛喜欢的食物和饮料的数量,接下来的Fi个整数表示第i头牛喜欢的食物的编号,最后Di个整数表示第i头牛喜欢的饮料的编号。

Output

输出同时得到喜欢的食物和饮料的牛的数量的最大值。

Sample Input

4 3 3
2 2 1 2 3 1
2 2 2 3 1 2
2 2 1 3 1 2
2 1 1 3 3

Sample Output

3

代码:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std;
#define inf 0x3f3f3f3f
#define ll long long
#define closeio std::ios::sync_with_stdio(false)
#define mem(a,b) memset(a,b,sizeof(a))

int g[505][505],path[505],flow[505],s,e,n;

queue<int >q;
int bfs()
{
	int i,t;
	while(!q.empty())
		q.pop();
	mem(path,-1);
	path[s]=0;
	flow[s]=inf;
	q.push(s);
	while(!q.empty())
	{
		t=q.front();
		q.pop();
		if(t==e)
			break;
		for(i=0;i<=n;i++)
		{
			if(i!=s&&path[i]==-1&&g[t][i])
			{
				flow[i]=flow[t]<g[t][i]?flow[t]:g[t][i];
				q.push(i);
				path[i]=t;
			}
		}
	}
	if(path[e]==-1)
		return -1;
	return flow[e];
}

int EK()
{
	int max_flow=0;
	int step,now,pre;
	while((step=bfs())!=-1)
	{
		max_flow+=step;
		now=e;
		while(now!=s)
		{
			pre=path[now];
			g[pre][now]-=step;
			g[now][pre]+=step;
			now=pre;
		}
	}
	return max_flow;
}

int main()
{
	int N,F,D,i;
	closeio;
	while(cin>>N>>F>>D)
	{
		mem(g,0);
		n=F+D+2*N+1;
		s=0;
		e=n;
		for(i=1;i<=F;i++)
			g[0][i]=1;
		for(i=F+2*N+1;i<=F+2*N+D;i++)
			g[i][n]=1;
		for(i=1;i<=N;i++)
			g[F+2*i-1][F+2*i]=1;
		int k1,k2,u;
		for(i=1;i<=N;i++)
		{
			cin>>k1>>k2;
			while(k1--)
			{
				cin>>u;
				g[u][F+2*i-1]=1;
			}
			while(k2--)
			{
				cin>>u;
				g[F+2*i][F+2*N+u]=1;
			}
		}
		cout<<EK()<<endl;
	}
	return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值