HDU2255(KB10-K 二分图最大权匹配)
Posted Penn000
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU2255(KB10-K 二分图最大权匹配)相关的知识,希望对你有一定的参考价值。
奔小康赚大钱
Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 10361 Accepted Submission(s): 4596
Problem Description
传说在遥远的地方有一个非常富裕的村落,有一天,村长决定进行制度改革:重新分配房子。
这可是一件大事,关系到人民的住房问题啊。村里共有n间房间,刚好有n家老百姓,考虑到每家都要有房住(如果有老百姓没房子住的话,容易引起不安定因素),每家必须分配到一间房子且只能得到一间房子。
另一方面,村长和另外的村领导希望得到最大的效益,这样村里的机构才会有钱.由于老百姓都比较富裕,他们都能对每一间房子在他们的经济范围内出一定的价格,比如有3间房子,一家老百姓可以对第一间出10万,对第2间出2万,对第3间出20万.(当然是在他们的经济范围内).现在这个问题就是村领导怎样分配房子才能使收入最大.(村民即使有钱购买一间房子但不一定能买到,要看村领导分配的).
这可是一件大事,关系到人民的住房问题啊。村里共有n间房间,刚好有n家老百姓,考虑到每家都要有房住(如果有老百姓没房子住的话,容易引起不安定因素),每家必须分配到一间房子且只能得到一间房子。
另一方面,村长和另外的村领导希望得到最大的效益,这样村里的机构才会有钱.由于老百姓都比较富裕,他们都能对每一间房子在他们的经济范围内出一定的价格,比如有3间房子,一家老百姓可以对第一间出10万,对第2间出2万,对第3间出20万.(当然是在他们的经济范围内).现在这个问题就是村领导怎样分配房子才能使收入最大.(村民即使有钱购买一间房子但不一定能买到,要看村领导分配的).
Input
输入数据包含多组测试用例,每组数据的第一行输入n,表示房子的数量(也是老百姓家的数量),接下来有n行,每行n个数表示第i个村名对第j间房出的价格(n<=300)。
Output
请对每组数据输出最大的收入值,每组的输出占一行。
Sample Input
2
100 10
15 23
Sample Output
123
Source
1 //2017-08-21 2 #include <cstdio> 3 #include <cstring> 4 #include <iostream> 5 #include <algorithm> 6 7 using namespace std; 8 9 const int N = 310; 10 const int INF = 0x3f3f3f3f; 11 int G[N][N]; 12 int n_x, n_y; 13 int matching[N], l_x[N], l_y[N]; 14 int slack[N]; 15 bool vis_x[N], vis_y[N]; 16 17 bool dfs(int u){ 18 vis_x[u] = 1; 19 for(int v = 0; v < n_y; v++){ 20 if(vis_y[v])continue; 21 int tmp = l_x[u]+l_y[v]-G[u][v]; 22 if(tmp == 0){ 23 vis_y[v] = 1; 24 if(matching[v] == -1 || dfs(matching[v])){ 25 matching[v] = u; 26 return true; 27 } 28 }else if(slack[v] > tmp){ 29 slack[v] = tmp; 30 } 31 } 32 return false; 33 } 34 35 int KM(){ 36 memset(matching, -1, sizeof(matching)); 37 memset(l_y, 0, sizeof(l_y)); 38 for(int u = 0; u < n_x; u++){ 39 l_x[u] = -INF; 40 for(int v = 0; v < n_y; v++) 41 if(G[u][v] > l_x[u]) 42 l_x[u] = G[u][v]; 43 } 44 for(int u = 0; u < n_x; u++){ 45 for(int i = 0; i < n_y; i++) 46 slack[i] = INF; 47 while(1){ 48 memset(vis_x, 0, sizeof(vis_x)); 49 memset(vis_y, 0, sizeof(vis_y)); 50 if(dfs(u))break; 51 int d = INF; 52 for(int i = 0; i < n_y; i++) 53 if(!vis_y[i] && d > slack[i]) 54 d = slack[i]; 55 for(int i = 0; i < n_x; i++) 56 if(vis_x[i]) 57 l_x[i] -= d; 58 for(int i = 0; i < n_y; i++){ 59 if(vis_y[i])l_y[i] += d; 60 else slack[i] -= d; 61 } 62 } 63 } 64 int ans = 0; 65 for(int i = 0; i < n_y; i++) 66 if(matching[i] != -1) 67 ans += G[matching[i]][i]; 68 return ans; 69 } 70 71 int main() 72 { 73 freopen("inputK.txt", "r", stdin); 74 int n; 75 while(scanf("%d", &n)!=EOF){ 76 for(int i = 0; i < n; i++){ 77 for(int j = 0; j < n; j++){ 78 scanf("%d", &G[i][j]); 79 } 80 } 81 n_x = n_y = n; 82 printf("%d\n", KM()); 83 } 84 85 return 0; 86 }
以上是关于HDU2255(KB10-K 二分图最大权匹配)的主要内容,如果未能解决你的问题,请参考以下文章