1. 程式人生 > >HDU2255(KB10-K 二分圖最大權匹配)

HDU2255(KB10-K 二分圖最大權匹配)

tle mat main eof 們的 esp slack div sca

奔小康賺大錢

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萬.(當然是在他們的經濟範圍內).現在這個問題就是村領導怎樣分配房子才能使收入最大.(村民即使有錢購買一間房子但不一定能買到,要看村領導分配的).

Input

輸入數據包含多組測試用例,每組數據的第一行輸入n,表示房子的數量(也是老百姓家的數量),接下來有n行,每行n個數表示第i個村名對第j間房出的價格(n<=300)。

Output

請對每組數據輸出最大的收入值,每組的輸出占一行。

Sample Input

2 100 10 15 23

Sample Output

123

Source

HDOJ 2008 Summer Exercise(4)- Buffet Dinner
 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 二分圖最大權匹配)