NOJ1077教练的礼物——网络最大流

44 篇文章 1 订阅

教练的礼物

时间限制(普通/Java):1000MS/3000MS          运行内存限制:65536KByte
总提交:39            测试通过:13

描述

南京邮电大学ACM程序设计竞赛校代表队成功晋级ACM/ICPC总决赛,教练老师非常高兴,特地从新西兰采购一批羊毛围巾和手套送出做出突出贡献的同学。但同学们各有所好,希望独自拥有一种型号的围巾或手套。请帮助教练老师分配这批礼物,使最多同学同时拥有自己喜欢的羊毛围巾和手套。

输入

第一行包括三个整数:N、C、D,分别表示做出突出贡献的同学人数、羊毛围巾的种类数、手套的种类数。 (1 ≤ N ≤ 100, 0 ≤ C ≤ 100,1 ≤ D ≤100)。

N行,每行对应一个同学对礼物的选择:

l       该同学所喜欢围巾的种类

l       该同学所喜欢手套的种类

l       该同学所喜欢围巾具体类型,依次给出类型号(以0,…,C表示)

l       该同学所喜欢手套具体类型,依次给出类型号(以0,…,D表示)

输出

 一行,同时拥有自己所喜欢围巾和手套的最多同学人数。

 

注意:输出部分的结尾要求包含一个多余的空行。

样例输入

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

样例输出

3

题目来源

“IBM南邮杯”个人赛2009


分析:网络最大流。此题很经典。关于网络流的算法需要多多理解!

关键在于构建模型:

源点(S)——围巾(C)建立一条边,流量为1

同学——喜欢的围巾(C)建立一条边,流量为1

同学——喜欢的手套(D)建立一条边,流量为1

手套(D)——汇点 (T)建立一条边,流量为1

关键:将学生的点拆开,在两端之间建立一条边,流量为1


求源点到汇点的最大流即为ans。因为每个人只能选择一个C和一个D。

我就采用了EK算法的模板。

int likeC[MAXN][MAXN];
int likeD[MAXN][MAXN];
int map[MAXN*4][MAXN*4];
int pre[MAXN*4];
queue<int> myque;
int N, C, D;

bool bfs(int src, int des)
{
	memset(pre, -1, sizeof(pre));
	while(!myque.empty()) myque.pop();
	pre[src] = 0;
	int index;
	myque.push(src);
	while(!myque.empty())
	{
		index = myque.front();
		myque.pop();
		for(int i=0;i<=des+1;i++) // des+1
		{
			if(pre[i] == -1 && map[index][i] > 0)
			{
				pre[i] = index;
				if(i == des) return true;
				myque.push(i);
			}
		}
	}
	return false;
}

int MaxFlow(int src, int des)
{
	int maxflow = 0;
	while(1)
	{
		if(!bfs(src, des)) break;
		int i = des;
		while(i != src)
		{
			map[pre[i]][i] -= 1;
			map[i][pre[i]] += 1;
			i = pre[i];
		}
		maxflow ++;
	}
	return maxflow;
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值