二分图的最大权匹配
来源:互联网 发布:mac进入屏保快捷键 编辑:程序博客网 时间:2024/06/04 18:46
二分图的带权匹配就是求出一个匹配集合,使得集合中边的权值之和最大(最小权匹配可以转化成最大权匹配,只要对取一个大数减去当前权值,或者取反)。
注意:最大权匹配必须是在保证该匹配是完备匹配的基础上权值和最大。而完备匹配是指一个匹配它包含二分图两个点集中某一个的全集(当然也可以包括这两个全集,也就是完备匹配)。
KM算法是通过给每个顶点一个标号(我们有时称之为顶标)来把求最大权匹配的问题转化为求完备匹配的问题的。我们令二分图中X部的节点的顶标为Ai,Y部的节点的顶标为Bi。X部与Y部节点之间的权值为Wi,j,那么,在算法进行的过程中,我们必须始终保持$A_i+B_i\geq W_{i,j}$成立。因为KM算法的正确性基于以下定理:
若由二分图中所有满足Ai+Bi=Wi,j的边 (i,j)构成的子图(称做相等子图)有完备匹配,那么这个完备匹配就是二分图的最大权匹配。(需要证明)
设slack[j]表示右边的点j的所有不在导出子图的边对应的lx[i]+ly[j]-w[i][j]的最小值,在find过程中,若某条边不在导出子图中就用它对相应的slack值进行更新。
交错树中,在 X 部顶点集称之为 S, 在 Y 部的顶点集称之为 T定义 slack(y)= min{ (x,y)| Lx(x)+ Ly(y)- W(x,y),x∈ S, y∉ T }这样能在寻找增广路径的时候就顺便将 slack 求出。
可以保证顶标的可行性,同时,经过这一步后,图中至少会增加一条可行边。
算法代码(@蛋丁http://www.cnblogs.com/-dante-/p/3269019.html):
bool dfs(int x)//匈牙利算法寻找x的增广路径 以x为根的M的交错树 { int y,t; visx[x]=true; for(y=0;y<N;y++) { if(visy[y]) continue;//找增广路径的过程中不妨问已经访问过的顶点 t=lx[x]+ly[y]-g[x][y];//在相等子图中寻找匹配的增广路径 if(t==0)//当前边时候是可行边 { visy[y]=true; if(linky[y]==-1||dfs(linky[y])) { linky[y]=x; return true; } } else//因为本来就需要将一条x顶点在交错树中,y顶点不在交错树中的边扩展进交错树来 //所以只改变这些不在等子图中的边的y顶点的松弛量 { if(slack[y]>t) slack[y]=t; } } return false;}//外层的匈牙利算法需要O(2)的时间,而修改顶标时由于要枚举所有的边所以也需要O(2)的时间//所以总时间是O(4) //引入松弛量以后改变顶标就不需要枚举每一条边,只需要枚举不在交错树中的y的松弛量,所以//时间复杂度降为O(3) int KM(){ int i,j,x,d,res=0; memset(linky,-1,sizeof(linky)); memset(lx,0,sizeof(lx));//x的顶标 memset(ly,0,sizeof(ly));//y的顶标 for(i=0;i<N;i++) for(j=0;j<N;j++) if(g[i][j]>lx[i]) lx[i]=g[i][j];//一开始x的顶标为所有与x相连的边中权值最大的边的权值,y的顶标为0 for(x=0;x<N;x++) {//在匈牙利算法中从每个x出发寻找增广路,如果找到就在匹配值上加1,这是为了寻找最大匹配 //而在此处,必须找到完备匹配,所以对于每一个x中的顶点,找到其增广路就跳出,找不到的话 //就需要修改顶标值直至找到为止 for(i=0;i<N;i++) slack[i]=INF; while(true) {//无限循环直至找到完备匹配 memset(visx,false,sizeof(visx)); memset(visy,false,sizeof(visy)); if(dfs(x))break;//若找到了曾广路,该点完成;若没有找到,需要修顶标,使得在dfs过程中可行边增多。 d=INF; for(i=0;i<N;i++) { if(!visy[i]&&d>slack[i]))//注意是取所有不在交错树中的y顶点的松弛量的最小值作为d的值 d=slack[i]; } for(i=0;i<N;i++) if(visx[i]) lx[i]-=d; for(i=0;i<N;i++) if(visy[i]) ly[i]+=d; else slack[i]-=d; } } for(i=0;i<N;i++) if(linky[i]!=-1) res+=g[linky[i]][i]; return res;}
相关问题转化:
KM(Kuhn-Munkres)算法求得的最大权匹配是边权值和最大,如果我想要边权之积最大,就每条边权取自然对数,然后求最大和权匹配,求得的结果a再算出e^a就是最大积匹配。
例题:
URAL1076:http://acm.timus.ru/problem.aspx?space=1&num=1076
poj 2195 Going Home(KM) :http://poj.org/problem?id=2195
参考文章:
byvoid二分图带权匹配 KM算法与费用流模型建立:https://www.byvoid.com/zhs/blog/match-km/
Kuhn-Munkres算法:http://www.nocow.cn/index.php/Kuhn-Munkres%E7%AE%97%E6%B3%95
McFlurry:http://www.cnblogs.com/mcflurry/archive/2013/01/24/2874114.html
蛋丁:http://www.cnblogs.com/-dante-/p/3269019.html
崔添翼的求最大权二分匹配的KM算法
张文泰:http://rchardx.is-programmer.com/posts/15306.html
呆呆的人v:http://blog.sina.com.cn/s/blog_691ce2b701016reh.html 这篇文章举得例子比较详细。
- 二分图的最大权匹配
- 二分图 最佳匹配 最大权匹配
- 最大权二分匹配
- 求二分图最大权匹配的km算法
- 【转】二分图最大权匹配的算法
- 完全二分图的最大权完美匹配 KM算法
- hdu 3722 Card Game 二分图的最大权匹配
- 初涉二分图的最大权匹配 KM算法
- hdu 2853Assignment (二分图的最大权匹配)
- hdu 3395(费用流,二分图的最大权匹配)
- KM算法模板(二分图的最大权匹配)
- 【最大权二分匹配的KM算法】
- 二分图最大权匹配算法模板
- 【二分图最大权匹配---KM算法】
- 二分图最大权匹配 (KM算法)
- 二分图最大权匹配-km算法
- 二分图最大权匹配-km算法
- 二分图最大权匹配 模板
- R引入其他统计软件数据的扩…
- indent格式化C代码
- 免费的天气预报webservice接口
- java版的memcached client及…
- ibatis基础上添加memcached缓存
- 二分图的最大权匹配
- Web服务入门之一:通过Xfire创建本…
- 如何设置其它进程中listctrl控件CHECKBOX的选中状态
- Axis2创建WebService实例
- 使用ksoap2 调用 WebSer…
- JS页面的跳转及刷新
- Windows安装memcached图文教程
- Siebel集成 - 符号URL的使用
- Qt 学习之路2(46)视图和委托---代码实现