Poj1274二分图最大匹配(匈牙利算法)
2016-02-25 09:14
218 查看
题目大意:有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;
大一时候写的,从网易博客移过来~
数据:
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; }
大一时候写的,从网易博客移过来~
相关文章推荐
- 简单的四则运算
- 数的奇偶性
- ACM网址
- 1272 小希的迷宫
- 1272 小希的迷宫
- hdu 1250 大数相加并用数组储存
- 矩阵的乘法操作
- 蚂蚁爬行问题
- 蚂蚁爬行问题
- 求两个数的最大公约数【ACM基础题】
- 打印出二进制中所有1的位置
- 杭电题目---一只小蜜蜂
- HDOJ 1002 A + B Problem II (Big Numbers Addition)
- 初学ACM - 半数集(Half Set)问题 NOJ 1010 / FOJ 1207
- 初学ACM - 组合数学基础题目PKU 1833
- POJ ACM 1001
- POJ ACM 1002
- 1611:The Suspects
- ACM题库以及培养策略
- 排序算法之快速排序