1. 程式人生 > 其它 >P1559 運動員最佳匹配問題

P1559 運動員最佳匹配問題

運動員最佳匹配問題

題目描述

羽毛球隊有男女運動員各n人。給定2 個n×n矩陣P和Q。P[i][j]是男運動員i和女運動員j配對組成混合雙打的男運動員競賽優勢;Q[i][j]是女運動員i和男運動員j配合的女運動員競賽優勢。由於技術配合和心理狀態等各種因素影響,P[i][j]不一定等於Q[j][i]。男運動員i和女運動員j配對組成混合雙打的男女雙方競賽優勢為P[i][j]\*Q[j][i]。設計一個演算法,計算男女運動員最佳配對法,使各組男女雙方競賽優勢的總和達到最大。

輸入輸出格式

輸入格式

第一行有1 個正整數n (1≤n≤20)。接下來的2n行,每行n個數。前n行是p,後n行是q。

輸出格式

將計算出的男女雙方競賽優勢的總和的最大值輸出。

輸入輸出樣例

輸入樣例 #1

3
10 2 3
2 3 4
3 4 5
2 2 2
3 5 3
4 5 1

輸出樣例 #1

52


 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <cstring>
 4 
 5 using namespace std;
 6 const int N = 40;
 7 int p[N][N];
 8 int n;
 9 int lx[N], ly[N];
10 int match[N];
11 int minz;
12 int visx[N], visy[N]; 13 14 bool dfs(int x) 15 { 16 visx[x] = 1; 17 for(int i = 1; i <= n; i++) 18 { 19 if(!visy[i]) 20 { 21 int t = lx[x] + ly[i] - p[x][i]; 22 if(t == 0) 23 { 24 visy[i] = 1; 25 if(match[i] == 0
|| dfs(match[i])) 26 { 27 match[i] = x; 28 return 1; 29 } 30 } 31 else if(t > 0) 32 { 33 minz = min(minz, t); 34 } 35 } 36 } 37 return 0; 38 } 39 40 void km() 41 { 42 for(int i = 1; i <= n; i++) 43 { 44 while(1) 45 { 46 minz = 0x7ffffff; 47 memset(visx, 0, sizeof visx); 48 memset(visy, 0, sizeof visy); 49 if(dfs(i)) break; 50 for(int j = 1; j <= n; j++) 51 { 52 if(visx[j]) lx[j] -= minz; 53 } 54 for(int j = 1; j <= n; j++) 55 { 56 if(visy[j]) ly[j] += minz; 57 } 58 } 59 } 60 } 61 62 int main() 63 { 64 scanf("%d",&n); 65 for(int i = 1; i <= n; i++) 66 { 67 for(int j = 1; j <= n; j++) 68 { 69 scanf("%d",&p[i][j]); 70 } 71 } 72 for(int i = 1; i <= n; i++) 73 { 74 for(int j = 1; j <= n ;j++) 75 { 76 int q; 77 scanf("%d",&q); 78 p[j][i] *= q; 79 } 80 } 81 82 for(int i = 1; i <= n; i++) 83 { 84 for(int j = 1; j <= n; j++) lx[i] = max(lx[i], p[i][j]); 85 } 86 87 km(); 88 int ans = 0; 89 for(int i = 1; i <= n; i++) 90 { 91 ans += p[match[i]][i]; 92 } 93 printf("%d",ans); 94 return 0; 95 }