HDU2255-奔小康赚大钱-二分图最大权值匹配-KM算法

二分图最大权值匹配问题。用KM算法。

最小权值的时候把权值设置成相反数

  1 /*--------------------------------------------------------------------------------------*/
  2
  3 #include <algorithm>
  4 #include <iostream>
  5 #include <cstring>
  6 #include <ctype.h>
  7 #include <cstdlib>
  8 #include <cstdio>
  9 #include <vector>
 10 #include <string>
 11 #include <queue>
 12 #include <stack>
 13 #include <cmath>
 14 #include <set>
 15 #include <map>
 16
 17 //debug function for a N*M array
 18 #define debug_map(N,M,G) printf("\n");for(int i=0;i<(N);i++) 19 {for(int j=0;j<(M);j++){ 20 printf("%d",G[i][j]);}printf("\n");}
 21 //debug function for int,float,double,etc.
 22 #define debug_var(X) cout<<#X"="<<X<<endl;
 23 #define LL long long
 24 const int INF = 0x3f3f3f3f;
 25 const LL LLINF = 0x3f3f3f3f3f3f3f3f;
 26 /*--------------------------------------------------------------------------------------*/
 27 using namespace std;
 28
 29 int N,M,T;
 30 const int maxn = 310;
 31 int nx,ny;
 32 int g[maxn][maxn];
 33 int linker[maxn],lx[maxn],ly[maxn];
 34 int slack[maxn];
 35 bool visx[maxn],visy[maxn];
 36 bool DFS(int x)
 37 {
 38     visx[x] = true;
 39     for(int y=0;y<ny;y++)
 40     {
 41         if(visy[y]) continue;
 42         int tmp = lx[x] + ly[y] - g[x][y];
 43         if(tmp == 0)
 44         {
 45             visy[y] = true;
 46             if(linker[y] == -1 || DFS(linker[y]))
 47             {
 48                 linker[y] = x;
 49                 return true;
 50             }
 51         }
 52         else if(slack[y] > tmp) slack[y] = tmp;
 53     }
 54     return false;
 55 }
 56 int KM()
 57 {
 58     memset(linker,-1,sizeof linker);
 59     memset(ly,0,sizeof ly);
 60     for(int i=0;i<nx;i++)
 61     {
 62         lx[i] = -INF;
 63         for(int j=0;j<ny;j++)   lx[i] = max(lx[i],g[i][j]);
 64     }
 65     for(int x=0;x<nx;x++)
 66     {
 67         for(int i=0;i<ny;i++) slack[i] = INF;
 68         while(true)
 69         {
 70             memset(visx,false,sizeof visx);
 71             memset(visy,false,sizeof visy);
 72             if(DFS(x)) break;
 73             int d = INF;
 74             for(int i=0;i<ny;i++) if(!visy[i] && d > slack[i]) d = slack[i];
 75             for(int i=0;i<nx;i++) if(visx[i]) lx[i] -= d;
 76             for(int i=0;i<ny;i++)
 77             {
 78                 if(visy[i]) ly[i] += d;
 79                 else slack[i] -= d;
 80             }
 81         }
 82     }
 83     int res = 0;
 84     for(int i=0;i<ny;i++) if(linker[i] != -1) res += g[linker[i]][i];
 85     return res;
 86 }
 87 int main()
 88 {
 89     while(~scanf("%d",&N))
 90     {
 91         for(int i=0;i<N;i++)
 92         {
 93             for(int j=0;j<N;j++)
 94             {
 95                 scanf("%d",&g[i][j]);
 96             }
 97         }
 98         nx = ny = N;
 99         printf("%d\n",KM());
100     }
101 }
时间: 2024-08-28 18:59:50

HDU2255-奔小康赚大钱-二分图最大权值匹配-KM算法的相关文章

HDU2255 奔小康赚大钱 —— 二分图最大权匹配

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2255 奔小康赚大钱 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 11022    Accepted Submission(s): 4877 Problem Description 传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行

[ACM] HDU 2255 奔小康赚大钱 (二分图最大权匹配,KM算法)

奔小康赚大钱 Problem Description 传说在遥远的地方有一个很富裕的村落,有一天,村长决定进行制度改革:又一次分配房子. 这但是一件大事,关系到人民的住房问题啊. 村里共同拥有n间房间,刚好有n家老百姓,考虑到每家都要有房住(假设有老百姓没房子住的话.easy引起不安定因素),每家必须分配到一间房子且仅仅能得到一间房子. 还有一方面,村长和另外的村领导希望得到最大的效益,这样村里的机构才会有钱.因为老百姓都比較富裕,他们都能对每一间房子在他们的经济范围内出一定的价格,比方有3间房

hdu2255 奔小康赚大钱,最大权匹配,KM算法

点击打开链接 最大权匹配 KM算法 算法步骤: 设顶点Xi的顶标为a[i],顶点Yi的顶标为b[i] ⅰ.初始时,a[i]为与Xi相关联的边的最大权值,b[j]=0,保证a[i]+b[j]>=w(i,j)成立 ⅱ.当相等子图中不包含完备匹配时,就适当修改顶标以扩大相等子图,直到找到完备匹配为止 ⅲ.修改顶标的方法 当从Xi寻找交错路失败后,得到一棵交错树,它的所有叶子节点都是X节点,对交错树中X顶点的顶标减少d值,Y顶点的顶标增加d值,对于图中所有的边(i,j), 可以看到: i和j都不在交错树

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

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

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

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

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> #

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家老百姓,考

HDU-2255 奔小康赚大钱(二分图、km算法、模板)

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

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

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