最大权完美匹配:二分图最大匹配是寻找最大匹配数,用匈牙利算法。当连 接的边带有权值时,要寻找匹配后权值和最大的方案,且保证 A 集合中的点均有 B 中的点能匹配。此时问题就转化为二分图最大权完美匹配。

KM 算法核心为: 为每一点添加顶标, 在顶标的限制下用匈牙利算法处理出最大匹配数, 若最大匹配数 =n, 则达到最优解, 输出。否则修改
顶标, 再用匈牙利算法处理, 如此重复。

设二分图的两部分点集分别为 X={X1,X2,…,Xn}X={X1,X2,…,Xn} 和 Y={Y1,Y2,…,Ym}Y={Y1,Y2,…,Ym}, ⟨Xi,Yj⟩⟨Xi,Yj⟩ 的边权为 wij
给两部分点集分别赋点权 {Ai},{Bi}{Ai},{Bi}, 使得 Ai+Bj⩾wij,取等的边的生成子图叫做相等子图。那么相等子图的完美匹配就是最大权匹配。我们需要适当选取权值,使相等子图有完美匹配。
算法步骤:
1.若成功(找到了增广轨),则该点增广完成,进入下一个点的增广
2.若失败(没有找到增广轨),则需要改变一些点的标号,使得图中可行边的数量增加。
操作为:将所有在增广轨中(就是在增广过程中遍历到)的X方点的标号全 部减去一个常数d,所有在增广轨中的Y方点的标号全部加上一个常数d
我也刚开始学习这个,也是跟着网上大佬的代码跟着敲的!

模版一:
#include <cstdio>
#include <cstring>
#include <algorithm>
#include<cmath>
#include<vector>
#include<stack>
using namespace std;
const int maxx=505;
const int inf = 0x3f3f3f3f;
int n;
int linker[maxx],lx[maxx],ly[maxx],slack[maxx];  //lx,ly为顶标
int visx[maxx],visy[maxx],w[maxx][maxx];
int DFS(int x){visx[x]=1;for(int y=1;y<=n;y++){if(visy[y])continue;    int tmp=lx[x]+ly[y]-w[x][y];   if(tmp==0){   visy[y]=1;if(linker[y]==-1 || DFS(linker[y])){   linker[y]=x;return 1;}}else {slack[y]=min(slack[y],tmp);}}return 0;
}int KM(){int i,j;memset(linker,-1,sizeof(linker));memset(ly,0,sizeof(ly));  for(i=1;i<=n;i++)      for(j=1,lx[i]=-inf;j<=n;j++){if(w[i][j]>lx[i]){lx[i]=w[i][j];} }for(int x=1;x<=n;x++){for(i=1;i<=n;i++){slack[i]=inf;}while(true){memset(visx,0,sizeof(visx));memset(visy,0,sizeof(visy));if(DFS(x))break;   int d=inf;for(i=1;i<=n;i++){if(!visy[i])d=min(slack[i],d);   }for(i=1;i<=n;i++){if(visx[i])lx[i]-=d;}for(i=1;i<=n;i++){if(visy[i]){ly[i]+=d;}else {slack[i]-=d;    }}            }}int res=0;for(i=1;i<=n;i++){if(linker[i]!=-1){res+=w[linker[i]][i];}}return res;
}
int main(){while(~scanf("%d",&n)){for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){scanf("%d",&w[i][j]);}}int ans=KM();printf("%d\n",ans);}return 0;
}
模版二:超时
#include<iostream>
#include<algorithm>
#include<stack>
#include<cmath>
#include<vector>
#include<cstring>
using namespace std;
const int maxx=500;
const int inf=0x3f3f3f3f;
int n,m,w[maxx][maxx];
int mb[maxx],vb[maxx],ka[maxx],kb[maxx],p[maxx],c[maxx];
int qf,qb,q[maxx];
void Bfs(int u){int a,v=0,vl=0,d;for(int i=1;i<=n;i++) {p[i]=0,c[i]=inf;}mb[v]=u;do {a=mb[v],d=inf,vb[v]=1;for(int b=1;b<=n;b++)if(!vb[b]){if(c[b]>ka[a]+kb[b]-w[a][b]){c[b]=ka[a]+kb[b]-w[a][b];p[b]=v;}if(c[b]<d) {d=c[b];vl=b;}}for(int b=0;b<=n;b++){if(vb[b]) {ka[mb[b]]-=d;kb[b]+=d;}else {c[b]-=d;}} v=vl;} while(mb[v]);while(v) {mb[v]=mb[p[v]];v=p[v];}
}
void init(){memset(ka,0,sizeof(ka));memset(kb,0,sizeof(kb));memset(mb,0,sizeof(mb));memset(p,0,sizeof(p));memset(vb,0,sizeof(vb));memset(c,0,sizeof(c));memset(q,0,sizeof(q));
}
int KM(){for(int a=1;a<=n;a++){for(int b=1;b<=n;b++) {vb[b]=0;}Bfs(a);}int res=0;for(int b=1;b<=n;b++) {res+=w[mb[b]][b];}return res;
}
int main(){while(scanf("%d",&n)){init();for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){scanf("%d",&w[i][j]);}}int ans=KM();cout<<ans<<endl;}return 0;
}

HDU2255(最全权完美匹配)相关推荐

  1. 二分图的最佳完美匹配(模板)

    二分图的最佳完美匹配,也就是带权值的无向二分图中权值之和最大的完美匹配,整个图分为两个不相交的集合x和y,采用KM算法求解,也称匈牙利算法. 时间复杂度为O(n^3) typedef int type ...

  2. poj3686(最小权值完美匹配)

    开始理解的有点简单了,也是看了其他的博客之后发现问题的: 题意:因为每一个物件都是受前一个物件的时间限制,所以假设某台机器加工了k个订单,那么用时为t1 + (t1 + t2) + (t1 + t2 ...

  3. HDU6346(最小权值完美匹配)

    题意:满足 xi+yj≤ai,j(1≤i,j≤n) 的约束下最大化∑ni=1xi+∑ni=1yi, 思路:采用最大权值完美匹配算法:但是现在这里是求最小权值完美匹配问题,所以只需要将权值取反最后在取反 ...

  4. HDU1533(最小权完美匹配)

    题意:m表示人,H表示房子,一个人只能进一个房子,一个房子也只能进去一个人,房子数等于人数,现在要让所有人进入房子,求所有人都进房子最短的路径. 思路:平时使用都是最大权完美匹配,现在这道题要求最小权 ...

  5. poj2195(最大权完美匹配)

    题意:m表示人,H表示房子,一个人只能进一个房子,一个房子也只能进去一个人,房子数等于人数,现在要让所有人进入房子,求所有人都进房子最短的路径. 思路:采用最大权完美匹配 最大权完美匹配:二分图最大匹 ...

  6. poj3565(最大权完美匹配)

    题意:让N只蚂蚁到一棵苹果树,给出N个蚂蚁和N棵苹果树的对应坐标,求权值就是求坐标点之间的距离表示,要求求出最小的距离! 思路:采用最大权完美匹配问题,但是现在这道题是求最小权值,可以将求得的坐标之间 ...

  7. HDU3718(最大权完美匹配)

    题意:先给出N个字母,代表要标签:再给出M行,和第一行给出的N个标签进行匹配,之间的差代表权值.最后的相似度为最大权值为ans*1.0/n. 最大权完美匹配:二分图最大匹配是寻找最大匹配数,用匈牙利算 ...

  8. HDU2853(最大权完美匹配)

    题意:要求改动公司数量最少并且效率最大(效率最大也就是最大完美匹配) 其中有一个最大的问题就是最少改变公司数量(也就是最少改变多少条边) 这个知识点我也是看了网上的,关于这个知识点我也感觉很神奇.除了 ...

  9. HDU3488(最大权完美匹配)

    题意:有N个城市M单程公路将它们连接起来:要求路路应该包含一个或多个循环a->B->-->p->A.每个城市都应该走一条路,在一条线路上,每个城市只需要访问一次,也就是一个城市 ...

最新文章

  1. R语言使用pie函数可视化饼图(pie chart)、为饼图添加百分比信息、使用plotrix包可视化3D饼图、使用plotrix包可视化扇形饼图
  2. 第二届数据标准化及治理奖评选顺利结束
  3. 使用小型变压器的线圈设计实验磁标初步实验
  4. sparkmllib scala GBDT Demo
  5. 数据库 SQL语法一
  6. CICD详解(三)——SVN基本概念
  7. django复习笔记2:models
  8. vi编辑器 末尾添加_VI编辑器的使用方法
  9. spss数据预处理步骤_2. SPSS基本使用:数据清洗
  10. robotframework使用之 下拉框的选择的几种用法
  11. (Excel)常用函数公式及操作技巧之六:汇总计算与统计(一)
  12. 爬取虾米音乐flac高品质下载
  13. Sql学习04(11.23-11.24)
  14. java库net2.0下载_visual j 2.0 下载-Visual J# 2.0(vjredist.exe)下载微软官方版-西西软件下载...
  15. 鸿蒙HarmonyOS应用开发系列 | 解读鸿蒙源码
  16. SpringBoot 雪花算法生成商品订单号【SpringBoot系列13】
  17. 【摘记】ABD-Net: Attentive but diverse Person Re-Id
  18. php 图片木马检测
  19. html制作简单框架网页 实现自己的音乐驿站 操作步骤及源文件下载 (播放功能限mp3文件)...
  20. You probably need to get an updated matplotlibrc file from解决方法

热门文章

  1. Python设计模式-中介者模式
  2. Django博客系统注册(定义用户模型类)
  3. https://www.exploit-db.com/下载POC比较完善的代码
  4. 计算机网络-编码与调制
  5. 有必要总结一下:matlab图像灰度调整——imadjust函数的使用
  6. 英语模板末尾【希望可以记着】
  7. pip经常的使用技巧
  8. 如何解决uiaotomator定位工具报错
  9. 在 Azure 中的 Linux VM 上创建 MongoDB、Express、AngularJS 和 Node.js (MEAN) 堆栈
  10. 关于Entity Framework自动关联查询与自动关联更新导航属性对应的实体注意事项说明...