匈牙利算法
来源:互联网 发布:淘宝哪家茶叶店靠谱 编辑:程序博客网 时间:2024/06/06 16:53
https://www.byvoid.com/blog/hungary
http://comzyh.com/blog/archives/148/
匈牙利算法是解决二分图匹配的问题。
二分图又称作二部图,是图论中的一种特殊模型。 设G=(V,E)是一个无向图,如果顶点V可分割为两个互不相交的子集(A,B),并且图中的每条边(i,j)所关联的两个顶点i和j分别属于这两个不同的顶点集(i in A,j in B),则称图G为一个二分图。
给定一个二分图G,M为G边集的一个子集,如果M满足当中的任意两条边都不依附于同一个顶点,则称M是一个匹配。
极大匹配(Maximal Matching)是指在当前已完成的匹配下,无法再通过增加未完成匹配的边的方式来增加匹配的边数。最大匹配(maximum matching)是所有极大匹配当中边数最大的一个匹配。选择这样的边数最大的子集称为图的最大匹配问题。(见下图)如图蓝线所示是一种最大二分匹配方案,匹配数=3
最大二分匹配
匈牙利算法过程
模拟步骤如右图所示(过于详细,大牛请无视):
- 初始化(清空)
- 从A所连接的点中找到一个未在本次循环中搜索过的点2,并将2标记为搜索过,因为2没有被连接过,匹配A2
- 结束上次,开始新的循环,将所有点标记为未搜索过
- 搜索B,找到一个未在本次循环中搜索过的点2,标记为搜索过
- 发现2被匹配过,从2的父亲A寻找增广路,递归搜索A{从A所连接的点中找到一个未在本次循环中搜索过的点5(1已经标记为绿色),将5标记为搜索过,因为5没有被匹配过,匹配A5}找到增广路(此处为增广路的关键)
- 结束上次,开始新的循环,将所有点标记为未搜索过
- 搜索C,找到一个未在本次循环中搜索过的点1,并将1标记为搜索过,发现1未被匹配过,匹配C1
- 结束上次,开始新的循环,将所有点标记为未搜索过
- 搜索D,找到一个未在本次循环中搜索过的点1,并将1标记为搜索过,发现1被匹配过,递归搜索1的源C寻找增广路
- {搜索C,找到一个未在本次循环中搜索过的点5,标记为搜索过,发现5被匹配,进一步返现没有其他可连接点,返回找不到增广路}返回第9步
- 搜索D,找到一个未在本次循环中搜索过的点2,发现2被匹配,递归搜索2的源B寻找增广路
- {搜索B,找到一个未在本次循环中搜索过的点3,并将3标记为搜索过,发现3未被匹配,匹配B3返回找到}既然B另寻新欢,匹配D2
- 结束上次,开始新的循环,将所有点标记为未搜索过,递归搜索D寻找增广路
- 搜索E,找到一个未在本次循环中搜索过的点2,并将2标记为搜索过,发现2被匹配过,递归搜索2的源D寻找增广路
- {搜索D,发现1,5均被匹配过,返回找不到增广路}
- E无其他可连接节点,放弃E,E后无后续节点,已经遍历A-E,结束算法
#include <iostream>#include <fstream>#include <stdlib.h>#include <memory.h>using namespace std;int tab[201][201];//邻接矩阵,不是真正意义的邻接矩阵,第一维对应牛,第二维对应牛棚int state[201],result[201];//stata:是否被搜索过;result:某牛栏对应的牛int n,m;int ans;//找到多少匹配int find(int x){// 匈牙利算法 int i; for (i=1;i<=m;i++){ if (tab[x][i]==1 && !state[i]){ state[i]=1;//标记为搜索过 if (result[i]==0//未被匹配过 || find(result[i])){//能找到一条增广路 result[i]=x;//匹配i,x return 1;//能找到新的匹配 } } } return 0; }int main(){ int i,j; int n1,t; cin >> n >> m; memset(tab,0,sizeof(tab)); for (i=1;i<=n;i++){ cin >> n1; for (j=1;j<=n1;j++){ cin >> t; tab[i][t]=1; } } for (i=1;i<=n;i++){ memset(state,0,sizeof(state));//清空是否搜索过数组 if (find(i)) ans++;//找到新的匹配 }//完成后 Result[i]保存着第i个牛栏对应的奶牛,本题不用输出,其他题有可能用 cout << ans<< endl; //system("pause"); return 0; }
0 0
- 匈牙利算法
- 匈牙利算法!!!
- 匈牙利算法
- 匈牙利算法
- 匈牙利算法
- 匈牙利算法
- 匈牙利算法
- 匈牙利算法
- 匈牙利算法
- 匈牙利算法
- 匈牙利算法
- 匈牙利算法
- 匈牙利算法
- 匈牙利算法
- 匈牙利算法
- 匈牙利算法
- 匈牙利算法
- 匈牙利算法
- Ubuntu下安装hadoop 2.X版本
- Hibernate中复合主键的配置和使用
- xStream完美转换XML、JSON
- [Swift]UIAlertController 以及 Swift 中的闭包和枚举
- 开始记录
- 匈牙利算法
- 高效率的测试者会在工作时做的4件事
- 双向循环链表
- Linux网络状态工具ss命令使用详解
- iOS开发asi使用(三)ASIHTTPRequest进度追踪
- 快速排序
- 在Linux中使用线程与线程的合并与分离
- Jibx 处理XML
- Android实现三级联动下拉框 下拉列表spinner的实例代码