二分图的最大匹配(匈牙利算法)
来源:互联网 发布:loveless world知乎 编辑:程序博客网 时间:2024/05/20 15:58
算法:二分图的匹配 ———— 最小路径覆盖
最小路径覆盖=最小路径覆盖=|G|-最大匹配数
二分图的最大匹配总结
int nx,ny;//x集合和y集合中顶点的个数 int edge[maxn][maxn];//edge[i][j]为1表示ij可以匹配 int cx[maxn],cy[maxn];//用来记录x集合中匹配的y元素是哪个! int visited[maxn];//用来记录该顶点是否被访问过! int path(int u) { int v; for(v=0;v<ny;v++) { if(edge[u][v]&&!visited[v]) { visited[v]=1; if(cy[v]==-1||path(cy[v]))//如果y集合中的v元素没有匹配或者是v已经匹配,但是从cy[v]中能够找到一条增广路 { cx[u]=v; cy[v]=u; return 1; } } } return 0; } int maxmatch() { int res=0; memset(cx,0xff,sizeof(cx));//初始值为-1表示两个集合中都没有匹配的元素! memset(cy,0xff,sizeof(cy)); for(int i=0;i<=nx;i++) { if(cx[i]==-1) { memset(visited,0,sizeof(visitited)); res+=path(i); } } return res; }</span>深度优先方法2:
/****************************************************二分图匹配(匈牙利算法的DFS实现)INIT:g[][]两边定点划分的情况CALL:res=hungary();输出最大匹配数优点:适于稠密图,DFS找增广路快,实现简洁易于理解时间复杂度:O(VE);****************************************************/const int MAXN=1000;int uN,vN; //u,v数目int g[MAXN][MAXN];//编号是0~n-1的 int linker[MAXN];bool used[MAXN];bool dfs(int u){ int v; for(v=0;v<vN;v++) if(g[u][v]&&!used[v]) { used[v]=true; if(linker[v]==-1||dfs(linker[v])) { linker[v]=u; return true; } } return false; } int hungary(){ int res=0; int u; memset(linker,-1,sizeof(linker)); for(u=0;u<uN;u++) { memset(used,0,sizeof(used)); if(dfs(u)) res++; } return res; }DFS就是利用增广路径的特性,为每个节点找到配对的点。核心是if (linker[v] == -1 || dfs(linker[v])),如果u可以和v配对,则直接返回;如果v已经有配对了,那么试试看能不能让v的对象另外再找个点配对,将v腾出来。然后一直递归下去。
广度优先遍历:
queue<int> Q;//Q队列,用来进行广度优先遍历int prev[__maxNodes];int Hungarian(){ int ans = 0; memset(matching, -1, sizeof(matching)); memset(check, -1, sizeof(check)); for (int i=0; i<num_left; ++i) { if(matching[i] == -1) { while (!Q.empty()) Q.pop(); Q.push(i); prev[i] = -1; // 设 i 为路径起点 bool flag = false; // 尚未找到增广路 while (!Q.empty() && !flag) { int u = Q.front(); for (iterator_t ix = G[u].begin(); ix != G[u].end() && !flag; ++ix) { int v = edges[*ix].to; if (check[v] != i) { check[v] = i; Q.push(matching[v]); //这里将matching[v]入队,如果matching[v]是-1的话,会直接进入下面的else,即 flag会变成true,到时候循环直接退出,-1也会被弹出。 //当matching[v]有值时,表示这个节点可以出现在树的下一层,所有加入到层序遍历队列中 if (matching[v] >= 0) //u可以和v配对,但是v已经有对象了,将u作为备胎记录下来 { // 此点为匹配点 prev[matching[v]] = u; //prev数组中存对应下标的点的备胎 } else { // 找到未匹配点,交替路变为增广路 flag = true; int d=u,e=v; while(d != -1) { //u原来是和t配对的,但是现在u甩了t和v配对 //所有t去找备胎配对 //依次循环下去 int t = matching[d]; matching[d] = e; matching[e] = d; d = prev[d]; e = t; } } } } Q.pop(); } if (matching[i] != -1) ++ans; } } return ans;}
看每新加入一个节点能不能形成新的增广路径。方法就是,以新加入的节点为根节点,生成匈牙利树,看是否能找到未匹配的叶子结点。如果有就说明加入当前节点后可以形成一条增广路径,及配对数加一。
阅读全文
0 0
- 匈牙利算法 (二分图的最大匹配)
- 二分图最大匹配的匈牙利算法
- 二分图最大匹配的匈牙利算法
- 二分图的最大匹配 (匈牙利算法)
- 二分图的最大匹配 匈牙利算法
- 二分图的最大匹配(匈牙利算法)
- 二分图的最大匹配:匈牙利算法
- 匈牙利算法-二分图的最大匹配
- 匈牙利算法,二分图的最大匹配
- (算法)二分图的最大匹配(匈牙利算法)
- 二分图最大匹配(匈牙利算法)
- 二分图最大匹配(匈牙利算法)
- 二分图最大匹配(匈牙利算法)
- 匈牙利算法(二分图最大匹配)
- 二分图最大匹配(匈牙利算法)
- 二分图最大匹配(匈牙利算法)
- 二分图最大匹配(匈牙利算法)
- 二分图最大匹配(匈牙利算法)
- 15 反射与动态执行
- 如何让CListCtrl选中行恒保持其蓝色高亮状态?
- MySQL事务隔离级别
- 16 Macros
- IllegalArgumentException occured : Parameter value [camera]was not matching type [java.lang.Double]
- 二分图的最大匹配(匈牙利算法)
- 17 Creating Languages
- 如何从零开始搭建个人博客(pages+hexo)
- C++Vector
- ThinkPhP3.2中图片添加,并生成缩略图
- 18 Concurrency and Synchronization
- ListView点击checkbox其他checkbox也被同时选中的问题
- 19 Performance
- Python Pillow Image Invert