Poj1274二分图最大匹配(匈牙利算法)

题目大意:有N头奶牛,M个产奶的棚子,每头奶牛都有自己想去产奶的几个棚子,问可以产生的最大匹配数。

数据:
Sample Input

5 5                           N M
2 2 5        第一头: t m2 m5
3 2 3 4     第二头: t m2 m3 m4
2 1 5        第三头:…..
3 1 2 5     第四头:…..
1 2           第五头:…..

Sample Output
4
解题思路:将奶牛看成N集合,棚子看成M集合
1,对于N集合中一个未匹配的节点i,寻找它的每条关联边,如果它的边上的另一个节点j还没匹配则表明找到了一个匹配,直接转步骤4;
2,假如节点i它边上的另一个节点j已经匹配,那么就转向跟j匹配的节点,也就是它的前驱,假设是pre[j],然后再对pre[j]重复1,2的步骤,即寻找增广路径.
3,假如我们在1,2步过程中找到一条增广路, 那么修改各自对应的匹配点,转步骤4,若无增广路, 则退出.
4,匹配数+1;


#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int Max = 201;
int N,M;
int arc[Max][Max];        //用邻接矩阵保存图
int visit[Max];           //访问标志
int pre[Max];             //匹配边集,前驱

int dfs(int i)
{
	for(int j = 1; j <= M; j++)
	{
		if(visit[j] == 0 && arc[i][j] == 1)  //搜索所有与i相邻的未访问点
		{
			visit[j] = 1;
			if(pre[j] == 0 || dfs(pre[j]))   //若j的前驱是未盖点或者存在由j的前驱出发的增广路径,则存在匹配边,返回1;
			{
				pre[j] = i;
				return 1;
			}
		}
	}
	return 0;
}

int main()
{
	int t,i;
	while(scanf("%d %d",&N,&M)!=EOF)
	{
		memset(arc,0,sizeof(arc));   //初始化
		memset(pre,0,sizeof(pre));
		for(i = 1; i <= N; i++)
		{
			scanf("%d",&t);
			for(int j = 1; j <= t; j++)
			{
				int x;
				scanf("%d",&x);
				arc[i][x] = 1;
			}
		}

		int ans = 0; //匹配边数
		for(i = 1; i <= N; i++)
		{
			memset(visit,0,sizeof(visit));
			if(dfs(i))       //若结点i被匹配边覆盖,则匹配边数+1
				ans++;
		}
		printf("%d\n",ans);
	}
	return 0;
}


大一时候写的,从网易博客移过来~



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值