码迷,mamicode.com
首页 > 其他好文 > 详细

USACO 奶牛食品(网络流)

时间:2015-08-04 22:57:35      阅读:584      评论:0      收藏:0      [点我收藏+]

标签:

题目大意:

FJ的奶牛们只吃各自喜欢的一些特定的食物和饮料,除此之外的其他食物和饮料一概不吃。某天FJ为奶牛们精心准备了一顿美妙的饭食,但在之前忘记检查奶牛们的菜单,这样显然是不能不能满足所有奶牛的要求。但是FJ又不愿意为此重新来做,所以他他还是想让尽可能多的牛吃到他们喜欢的食品和饮料。

FJ提供了F (编号为1、2、…、F)种食品并准备了D (编号为1、2、…、D)种饮料, 他的N头牛(编号为1、2、…、N)都已决定了是否愿意吃某种食物和喝某种饮料。FJ想给每一头牛一种食品和一种饮料,使得尽可能多的牛得到喜欢的食物和饮料。

每一种食物和饮料只能由一头牛来用。例如如果食物2被一头牛吃掉了,没有别的牛能吃到食物2。

(原谅我找不到原题,只有把学校OJ的题粘过来)


思路:网络流的模板题,f作为左边一部,n作为中间一部,d作为右边一部,起点向f部连边,d部向终点连边。

#include<cstdio>
#define MAXN 310
#define Min(a,b) a<b?a:b
#define INF 999999999
#define BIG 123456789
using namespace std;
int c[MAXN][MAXN];
int dd[MAXN];
int vd[MAXN];
int s,t,n,f,d,flow;
int aug(int u,int augco)
{
	int j,augc = augco,mind = t,delta;
	if(u == t) return augco;
	for(j = 0; j <= t; j++)
	if(c[u][j])
	{
		if(dd[u] == dd[j]+1)
		{
			delta = Min(c[u][j],augc);
			delta = aug(j,delta);
			c[u][j] -= delta;
			c[j][u] += delta;
			augc -= delta;
			if(dd[s] > t) return augco - augc;
			if(augc == 0) break;
		}
		mind = Min(mind,dd[j]);
	}
	if(augco == augc)
	{
		vd[dd[u]]--;
		if(vd[dd[u]] == 0) dd[s] = t+1;
		dd[u] = mind+1;
		vd[dd[u]]++;
	}
	return augco - augc;
}
void sap()
{
	vd[0] = t+1;
	while(dd[s] < t+1)
		flow += aug(s,BIG);
}
int main()
{
	int p1,p2,v;
	scanf("%d%d%d",&n,&f,&d);
	for(int i = 1; i <= n; i++)
	{
		scanf("%d%d",&p1,&p2);
		for(int j = 1; j <= p1; j++)
		{	
			scanf("%d",&v);
			c[v][f+i] = 1;
		}	
		for(int j = 1; j <= p2; j++)
		{
			scanf("%d",&v);
			c[n+i][n+f+v] = 1;
		}
	}
	s = 0;
	t = n+f+d+1;
	for(int i = 1; i <= f; i++)
		c[s][i] = 1;
	for(int i = 1; i <= d; i++)
		c[n+f+i][t] = 1;
	sap();
	printf("%d\n",flow);
}


版权声明:本文为博主原创文章,未经博主允许不得转载。

USACO 奶牛食品(网络流)

标签:

原文地址:http://blog.csdn.net/cqbzwja/article/details/47283229

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!