KM算法大概过程:

  (1)初始化Lx数组为该boy的一条权值最大的出边。初始化Ly数组为 0。

  (2)对于每个boy,用DFS为其找到一个girl对象,顺路记录下S和T集,并更新每个girl的slack值。若不能为其找到对象,则转3。

  (3)找出非T集合的girl的最小slack值为d,更新S集中的boy和T集中的girl,并且顺路更新非T集中的slack值。对于那个失败的boy继续第2步。

  简括之,就是在保持当前权和最高的情况下,尽量为每个boy找到权更大的边。找的过程就是DFS过程,标记出S和T集是为了保证权和最大,因为只要帮S中任意一个boy另找一个女对象,为这个boy的此次脱单之路告终。

  DFS的要完成的任务:

  (1)标记S和T集。

  (2)更新每个girl的slack值为最小。

  模板还是必须的,带满了注释,改自kuangbin的模板。

 /* KM算法:复杂度O(nx*nx*ny)
* 完全二分图求最大权匹配(必须为所有boy找到对象,且boy数量必须<=girl数量)
* 若求最小权匹配,可将权值取相反数,结果取相反数
* 点的编号从1开始。
* 以男女模型出现比较直观。
*/
int nx, ny; //两边的点数,x为男,y为女。
int g[N][N]; //二分图描述,g[x][y]表示边权。
int girl[N], Lx[N], Ly[N]; //girl[i]记录i的匹配成功对象,男女的顶标
int slack[N]; //为了优化用的,连接到对应girl的松弛值。
bool S[N], T[N]; //匈牙利树的节点集合,S为男,T为女。 bool DFS(int x) // x一定是boy
{
S[x]=true;
for(int i=; i<=ny; i++) //枚举girl
{
if(T[i]) continue;
int tmp=Lx[x]+Ly[i]-g[x][i];
if( tmp== )
{
T[i]=true;
//为第i个girl的男对象另找女对象
if(girl[i]==- || DFS(girl[i]))
{
girl[i]=x; //记录匹配的boy
return true;
}
}
else if(slack[i]>tmp) //顺便更新下slack
slack[i]=tmp;
}
return false;
} int KM()
{
memset(girl, -, sizeof(girl));
memset(Ly, , sizeof(Ly));
for(int i=; i<=nx; i++) //初始化两个L数组分别为-INF和0
{
Lx[i] = -INF;
for(int j=; j<=ny; j++)
if(g[i][j]>Lx[i]) Lx[i]=g[i][j];
}
for(int j=; j<=nx; j++) //枚举boy
{
for(int i=; i<=ny; i++) //初始slack为无穷。slack只需要记录girl的。
slack[i]=INF;
while(true) //无限循环,直到帮boy[j]找到对象
{
memset(S, , sizeof(S));
memset(T, , sizeof(T));
if( DFS(j) ) break; //直接就找到对象了,搞定。
int d=INF;
for(int i=; i<=ny; i++) //根据不在匈牙利树上的girl的slack值找到最小值d
if(!T[i] && d>slack[i])
d=slack[i];
for(int i=; i<=nx; i++) //所有匈牙利树上的boy更新lx值
if(S[i]) Lx[i]-=d;
for(int i=; i<=ny; i++) //树上的girl加d,不在树上的girl的slack减d。
{
if(T[i]) Ly[i]+=d; //这是为了让等式仍然成立
else slack[i]-=d;
}
}
}
int ans=;
for(int i=; i<=ny; i++) //累计匹配边的权和
if(girl[i]>) ans+=g[girl[i]][i];
return ans;
}

KM算法

  

KM算法(二分图的最佳完美匹配)的更多相关文章

  1. 二分图学习记 之 KM算法 二分图最大权完美匹配。

    前置知识 :匈牙利算法 首先有这样一张图,求这张图的最大权完美匹配. 当然如果你不想看这些渣图的话,您可以转到 洛谷 运动员最佳匹配问题 下面我来强行解释一下KM算法 左边一群妹子找汉子,但是每个妹子 ...

  2. hdu1533 Going Home km算法解决最小权完美匹配

    Going Home Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total ...

  3. poj3565 Ants km算法求最小权完美匹配,浮点权值

    /** 题目:poj3565 Ants km算法求最小权完美匹配,浮点权值. 链接:http://poj.org/problem?id=3565 题意:给定n个白点的二维坐标,n个黑点的二维坐标. 求 ...

  4. HDU 2255 KM算法 二分图最大权值匹配

    奔小康赚大钱 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Subm ...

  5. UVa1349 Optimal Bus Route Design(二分图最佳完美匹配)

    UVA - 1349 Optimal Bus Route Design Time Limit: 3000MS Memory Limit: Unknown 64bit IO Format: %lld & ...

  6. 【模板】二分图最大权完美匹配KM算法

    hdu2255模板题 KM是什么意思,详见百度百科. 总之知道它可以求二分图最大权完美匹配就可以了,时间复杂度为O(n^3). 给张图. 二分图有了边权,求最大匹配下的最大权值. 所以该怎么做呢?对啊 ...

  7. 【二分图最大权完美匹配】【KM算法】【转】

    [文章详解出处]https://www.cnblogs.com/wenruo/p/5264235.html KM算法是用来求二分图最大权完美匹配的.[也就算之前的匈牙利算法求二分最大匹配的变种??] ...

  8. 二分图最大权完美匹配KM算法

    KM算法二分图 KM求得二分图与普通二分图的不同之处在于:此二分图的每条边(男生女生)上都附了权值(好感度).然后,求怎样完美匹配使得权值之和最大. 这,不止一般的麻烦啊. 可以通过一个期望值来求. ...

  9. 【模板】二分图最大权完美匹配(KM算法)/洛谷P6577

    题目链接 https://www.luogu.com.cn/problem/P6577 题目大意 给定一个二分图,其左右点的个数各为 \(n\),带权边数为 \(m\),保证存在完美匹配. 求一种完美 ...

随机推荐

  1. php string转换为int

    本身 var_dump : string(3) "002" 本身 is_numeric : bool(true) 本身 转换为数字 : int(2) 本身 转换为数字变量 : in ...

  2. 同一网站不同和二级域名和不同子目录的cookie

    1.cookie二级域名的实现: 用户其中一个站点登录,而且可以各个子频道间切换,保持登录状态设置Cookie时,使用如下代码即可:setcookie(name,value,expire,path,& ...

  3. Java package详解

    Java引入包(package)机制,提供了类的多层命名空间,用于解决类的命名冲突.类文件管理等问题.Java允许将一组功能相关的类放在同一个package下,从而组成逻辑上的类库单元.如果希望把一个 ...

  4. 屏蔽wordpress升级提示

    根据自己的需要,挑选适合的代码放在主题的functions.php文件中就可以了 /* 去除 WordPress 後台升級提示 */ // 2.8 ~ 2.9: add_filter('pre_tra ...

  5. 机器学习之多变量线性回归(Linear Regression with multiple variables)

    1. Multiple features(多维特征) 在机器学习之单变量线性回归(Linear Regression with One Variable)我们提到过的线性回归中,我们只有一个单一特征量 ...

  6. linux下如何查看主机的外网ip地址

    在linux下如果我们使用的是nat方式上网.通过ifconfig命令查看到的ip地址往往是内网地址 那么如何查看主机在互联网上使用的公网IP呢?我们可以在命令行下使用curl命令实现这个功能. [r ...

  7. SQL Server 2008管理工具出现 远程过程调用失败0x800706be解决方法

    解决方法 出现此问题是因为在安装 Visual Studio 2012(VS2012) 时,会自动安装 "Microsoft SQL Server 2012 Express LocalDB& ...

  8. redis系列之Redis应用场景

    1 取最新N个数据的操作 比如典型的取你网站的最新文章,通过下面方式,我们可以将最新的5000条评论的ID放在Redis的List集合中,并将超出集合部分从数据库获取 1)使用LPUSH latest ...

  9. E时代主机,其实做一个小虚拟主机还是不错的

    http://www.idcen.com/ 做微信没有网上测试地址,找了一下发现以前用过的.记录一下.一个100m的虚拟主机需要三四十块钱,做微信,做一个小型网站还是够用的,就是mysql有点问题,不 ...

  10. Android笔记——PreferenceActivity结合PreferenceFragment创建设置界面

    1.创建类继承PreferenceActivity 2.该类必须重写OnBuildHeaders和isValidFragment方法.         (1)OnBuildHeaders方法中使用lo ...