【km算法模板+总结】

今天下午看了一下午的km算法,因为大佬的博客介绍非常简短,所以自己一直没有弄清楚一些细节问题,好在回来翻到了一个比较好的csdn专栏,介绍比较详细,自己才算弄懂了很多疑惑的地方,二分图最佳完美匹配

总结一下算法:

思想:km算法就是改变一些可行点的标号,不断增加图中可行边的总数,直到图中存在仅由可行边组成的完美匹配为止。核心部分就是控制修改可行顶标的值直到最终可到达一个完美匹配。

流程:1)初始化可行顶标lx和ly的值(ly=0显然是可行的,保证任意x一个x方点至少一条可行边)

   2)从每个x方点开始dfs增广,用匈牙利算法寻找相等子图的完备匹配。

   3)如果没有找到增广路,改变可行顶标的值。

   4)重复2)3)直到找到相等子图的完备匹配。

注意两点:一是只找可行边,二是要把搜索过程中遍历到的X方点全部记下来,以便进行后面的修改

 1 #define INF 0x3f3f3f3f
 2 int dfs(int x)
 3 {
 4     int y,tmp;
 5     visx[x] = 1;
 6     for(y = 1; y <= ny; y ++)
 7     {
 8         if(!visy[y])
 9         {
10             tmp = lx[x] + ly[y] - w[x][y];
11             if(tmp == 0)
12             {
13                 visy[y] = 1;
14                 if(linker[y]==-1||dfs(linker[y]))
15                 {
16                     linker[y] = x;
17                     return 1;
18                 }
19             }
20             else if(slack[y] > tmp)
21                 slack[y] = tmp;//x,y不在相等子图中且y不在增广轨中
22         }
23     }
24     return 0;
25 }
26 int km()
27 {
28     int x,y,sum,i,d,j;
29     memset(linker,-1,sizeof(linker));
30     memset(ly,0,sizeof(ly));
31     for(i = 1; i <= nx; i ++)
32         for(j = 1, lx[i] = -INF; j <= ny; j ++)
33             if( lx[i] < w[i][j])
34                 lx[i] = w[i][j];
35     for(x = 1; x <= nx; x ++)
36     {
37         for(i = 1; i <= ny; i ++)
38             slack[i] = INF;//每次换新的结点都要初始化slack
39         while(1)
40         {//因为每次dfs都需要更新
41             memset(visx,0,sizeof(visx));
42             memset(visy,0,sizeof(visy));
43             if(dfs(x))
44                 break;
45             //dfs失败,所以x一定在增广轨中,y一定不在增广轨中
46             d = INF;
47             for(i = 1; i <= ny; i ++)
48                 if(!visy[i]&&d > slack[i])
49                     d = slack[i];
50             for(i = 1; i <= nx; i ++)
51                 if(visx[i])
52                     lx[i] -=d;
53             for(i = 1; i <= ny; i ++)
54                 if(visy[i])
55                     ly[i] +=d;
56                 else
57                     slack[i] -=d;//修改顶标之后,将所有的slack减去d
58         //因为lx减去了d,而slack[y]=lx[x]-ly[y]-w[x][y].而y是不在增广轨中的,第二类边
59         }
60     }
61     sum = 0;
62     for(i = 1; i <= ny; i ++)
63         if(linker[i]!=-1)
64             sum += w[linker[i]][i];
65     return sum;
66 }
时间: 2024-10-06 01:00:17

【km算法模板+总结】的相关文章

hdu 2255奔小康赚大钱 KM算法模板

题目链接:http://acm.hdu.edu.cn/showproblem.php? pid=2255 一,KM算法:(借助这个题写一下个人对km的理解与km模板) KM算法主要是用来求解图的最优匹配的. 1.带权二分图:  在二分图中每一条边(x.y)相应一个权值Wi这样的二分图叫带权二分图. 一个匹配的权值就是该匹配中全部边的权值之和. 2,最优匹配: 权值最大的一个完美匹配.叫做最优匹配.       <km算法思想> 对于一个带权全然二分图:G(V.E),对于当中每一条边(x.y)边

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

[文章详解出处]https://www.cnblogs.com/wenruo/p/5264235.html KM算法是用来求二分图最大权完美匹配的.[也就算之前的匈牙利算法求二分最大匹配的变种??] 这里就贴一下模板代码..2333... 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <algorithm> 5 using namespace std; 6

二分图最大权值匹配 KM算法 模板

大佬讲的太好了!!!太好了!!! http://www.cnblogs.com/wenruo/p/5264235.html KM算法用来求二分图最大权完美匹配. 本文配合该博文服用更佳:趣写算法系列之--匈牙利算法 本文没有给出KM算法的原理,只是模拟了一遍算法的过程.另,博主水平较差,发现问题欢迎指出,谢谢!!!! 现在有N男N女,有些男生和女生之间互相有好感,我们将其好感程度定义为好感度,我们希望把他们两两配对,并且最后希望好感度和最大. 怎么选择最优的配对方法呢? 首先,每个女生会有一个期

hdu 2255 奔小康赚大钱 (km算法模板)

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=2255 解题思路: 了解km算法以后,就可以直接套用km算法,km算法:完备匹配下的最大权匹配, 代码: 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 using namespace std; 6 7 #define maxn 310

poj 2195(KM算法模板)

Going Home Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 18094   Accepted: 9225 Description On a grid map there are n little men and n houses. In each unit time, every little man can move one unit step, either horizontally, or vertical

HDU 2255 奔小康赚大钱 (KM算法 模板)

A - 奔小康赚大钱 Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Description 传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子. 这可是一件大事,关系到人民的住房问题啊.村里共有n间房间,刚好有n家老百姓,考虑到每家都要有房住(如果有老百姓没房子住的话,容易引起不安定因素),每家必须分配到一间房子且只能得到一间房子.

hdu 2255(KM算法模板)

奔小康赚大钱 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3707    Accepted Submission(s): 1618 Problem Description 传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子. 这可是一件大事,关系到人民的住房问题啊.村里共有n间房间,刚好有n家老百姓,考

KM算法(二分图的最佳完美匹配)

网上一堆人写KM算法,还没搜出哪个讲得比较好的. 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步. 简括之,就是在保持当前权和最高的情况下,尽量为每个bo

hdu2255 奔小康赚大钱 km算法解决最优匹配(最大权完美匹配)

/** 题目:hdu2255 奔小康赚大钱 km算法 链接:http://acm.hdu.edu.cn/showproblem.php?pid=2255 题意:lv 思路:最优匹配(最大权完美匹配) km算法 模板来自:http://www.cnblogs.com/wenruo/p/5264235.html 如果是求最小权完美匹配,那么将所有权值取相反数,然后求得最大权,输出最大权的相反数即可. */ #include <iostream> #include <cstring> #