二分图'最佳匹配' KM算法

讲得很清楚的博客  推荐! 点我??

附上一模板题 // hdu 2255(求最大权和)

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 const int INF = 0x3f3f3f3f;
 5 const int MAXN = 300+5;
 6
 7 int n;
 8 int w[MAXN][MAXN];// 权值数组
 9 int cx[MAXN], cy[MAXN];// "标杆" --核心
10
11 int love[MAXN];
12 bool visx[MAXN], visy[MAXN];
13
14 bool dfs(int u) {
15     visx[u] = true;
16     for(int v = 1; v <= n; ++v) {
17         if(!visy[v] && cx[u] + cy[v] == w[u][v]) {
18             visy[v] = true;
19             if(!love[v] || dfs(love[v])) {
20                 love[v] = u;
21                 return true;
22             }
23         }
24     }
25     return false;
26 }
27
28 int KM() {
29     for(int i = 1; i <= n; ++i) love[i] = 0;
30     for(int i = 1; i <= n; ++i) {
31         while(1) {
32             for(int j = 1; j <= n; ++j) visx[j] = visy[j] = false;
33             if(dfs(i)) break;
34             int d = INF;
35             for(int j = 1; j <= n; ++j) {
36                 if(visx[j]) {
37                     for(int k = 1; k <= n; ++k) {
38                         if(!visy[k]) d = min(d, cx[j]+cy[k]-w[j][k]);
39                     }
40                 }
41             }
42             for(int i = 1; i <= n; ++i) {
43                 if(visx[i]) cx[i] -= d;
44                 if(visy[i]) cy[i] += d;
45             }
46         }
47     }
48     int ans = 0;
49     for(int i = 1; i <= n; ++i) {
50         ans += w[love[i]][i];
51     }
52     return ans;
53 }
54
55 int main() {
56     while(scanf("%d", &n) == 1) {
57         for(int i = 1; i <= n; ++i) {
58             int d = 0;
59             for(int j = 1; j <= n; ++j) {
60                 scanf("%d", &w[i][j]);
61                 d = max(d, w[i][j]);
62             }
63             cx[i] = d;
64             cy[i] = 0;
65         }
66         printf("%d\n", KM());
67     }
68     return 0;
69 }

// hdu 3488 (最小权值和)

 1 #include<cstdio>
 2 #include<algorithm>
 3 #include<set>
 4 using namespace std;
 5 const int INF = 0x3f3f3f3f;
 6 const int MAXN = 200+5;
 7
 8 int n, m;
 9 int w[MAXN][MAXN];
10 int cx[MAXN], cy[MAXN];
11
12 int love[MAXN];
13 bool visx[MAXN], visy[MAXN];
14
15 bool dfs(int u) {
16     visx[u] = true;
17     for(int v = 1; v <= n; ++v) {
18         if(!visy[v] && cx[u] + cy[v] == w[u][v]) {
19             visy[v] = true;
20             if(!love[v] || dfs(love[v])) {
21                 love[v] = u;
22                 return true;
23             }
24         }
25     }
26     return false;
27 }
28
29 int KM() {
30     for(int i = 1; i <= n; ++i) love[i] = 0;
31     for(int i = 1; i <= n; ++i) {
32         while(1) {
33             for(int j = 1; j <= n; ++j) visx[j] = visy[j] = false;
34             if(dfs(i)) break;
35             int b = INF;
36             for(int j = 1; j <= n; ++j) {
37                 if(visx[j]) {
38                     for(int k = 1; k <= n; ++k) {
39                         if(!visy[k]) b = min(b, cx[j] + cy[k] - w[j][k]);
40                     }
41                 }
42             }
43             for(int j = 1; j <= n; ++j) {
44                 if(visx[j]) cx[j] -= b;
45                 if(visy[j]) cy[j] += b;
46             }
47         }
48     }
49     int ans = 0;
50     for(int i = 1; i <= n; ++i) {
51         ans += w[love[i]][i];
52     }
53     return -ans;
54 }
55
56 int main() {
57     int T;
58     scanf("%d", &T);
59     while(T--) {
60         scanf("%d%d", &n, &m);
61         for(int i = 1; i <= n; ++i) for(int j = 1; j <= n; ++j) w[i][j] = -INF;
62         int x, y, v;
63         set<int> xx[MAXN];
64         for(int i = 0; i != m; ++i) {
65             scanf("%d%d%d", &x, &y, &v);
66             if(-v > w[x][y]) w[x][y] = -v, xx[x].insert(v);
67         }
68         for(int i = 1; i <= n; ++i) {
69             cx[i] = -*xx[i].begin();
70             cy[i] = 0;
71         }
72         printf("%d\n", KM());
73     }
74     return 0;
75 }

二分图'最佳匹配' KM算法

原文地址:https://www.cnblogs.com/pupil-xj/p/11802482.html

时间: 2025-01-06 21:23:15

二分图'最佳匹配' KM算法的相关文章

hdu2255 奔小康赚大钱 二分图最佳匹配--KM算法

传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子.这可是一件大事,关系到人民的住房问题啊.村里共有n间房间,刚好有n家老百姓,考虑到每家都要有房住(如果有老百姓没房子住的话,容易引起不安定因素),每家必须分配到一间房子且只能得到一间房子.另一方面,村长和另外的村领导希望得到最大的效益,这样村里的机构才会有钱.由于老百姓都比较富裕,他们都能对每一间房子在他们的经济范围内出一定的价格,比如有3间房子,一家老百姓可以对第一间出10万,对第2间出2万,对第3间出20万.(

HDU2255 奔小康赚大钱 【二分图最佳匹配&#183;KM算法】

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

ACM学习历程—POJ3565 Ants(最佳匹配KM算法)

Young naturalist Bill studies ants in school. His ants feed on plant-louses that live on apple trees. Each ant colony needs its own apple tree to feed itself. Bill has a map with coordinates of n ant colonies and n apple trees. He knows that ants tra

Regionals 2015 &gt;&gt; Asia - Tehran &gt;&gt; 7530 - Cafebazaar【二分图最佳匹配】【KM】【最大费用流】

Regionals 2015 >> Asia - Tehran >> 7530 - Cafebazaar 题目链接:7530 题目大意:一个公司有n个开发者,有m个APP可开发.其中一些开发者必选,一些APP必选.已知每个开发者开发每个APP的收益,求最大收益.(每个开发者最多开发一个APP,每个APP最多一个人开发) 题目思路: 解法一:二分图最佳匹配(KM算法) 增加一些虚开发者和虚app,非必要app可以被虚开发者开发,收益为0,反过来非必要开发者可以开发虚app,收益为0.

训练指南 UVALive - 4043(二分图匹配 + KM算法)

layout: post title: 训练指南 UVALive - 4043(二分图匹配 + KM算法) author: "luowentaoaa" catalog: true mathjax: true tags: - 二分图匹配 - 图论 - 训练指南 Ants UVALive - 4043 题意 给你n个白点和n个黑点的平面坐标,要求用n条不相交的线连起来,每条线段连一个白点和黑点,每个点连一条线,也就是匹配.让你输出第i个白点所对应的黑点. 思路 二分图完美匹配问题.但是题目

POJ 2195 二分图最小权匹配KM算法

本来是打算昨天晚上写的, 昨天网速渣的连CSDN都进不去,没办法 只能现在来写了 先写写对KM算法的理解,KM算法是对每个点设置一个顶标,只有当边长等于两边点的顶标之和的时候才进行增广,这样就能保证得到的一定是最大权匹配. 如果找不到匹配的时候就对交替路中X集合的顶标减少一个d Y集合的顶标增加一个d. 这样两个点都在交替路中的时候x[i]+y[i]的和不边 X在 Y不在的时候x[i]+y[i]减少,可能就会为图增加一对匹配. X不在Y在的时候x[i]+y[i]增加, 原来不在现在依然不在其中.

带权二分图的最大权匹配 KM算法模版

带权二分图的最大权匹配 KM算法模版 下面是kuangbin大神的模版,已通过西电oj1048的测试 #include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<vector> #include<stack> #include<queue> #include<set

HDU2255 奔小康赚大钱【二分图最佳匹配】

题目链接: http://acm.hdu.edu.cn/showproblem.php? pid=2255 题目大意: 村里要分房子. 有N家老百姓,刚好有N间房子.考虑到每家都要有房住,每家必须分配到一间房子且 仅仅能分配到一间房子.另外, 村长为了得到最大利益,让老百姓对房子进行估价. 比方有3件房子,一 家老百姓能够对第一间出10万,对第二间出2万,对第三间出4万.第二家老百姓能够对第一间出8万, 对第二家出3万,对第三间出5万.那么问题来了:怎么分配,才干使利益最大化. (村民房子不一定

POJ2195 Going Home【二分图最佳匹配】

题目链接: http://poj.org/problem?id=2195 题目大意: 在一个N*M的矩阵中,有M个人和M个房子,每个人要安排一个房子,每个房子只能安排一个人. 而每个人移动一步需要一美元.那么问题来了:求为每个人安排房子移动所需要的金钱最小值是多 少. 思路: 做一个二分图,一边为人,另一边为房子,如果把人和房子之间的距离作为边权的话,问题就变成 了求带权二分图最小权和的最佳匹配.这里我们为了方便计算,吧人和房子之间的距离的负值作为 边权,那么就变成了求带权二分图最大权和的最佳匹