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 }
View Code

 

 

 

 
posted @ 2021-07-09 22:00  lyc_lb  阅读(99)  评论(0)    收藏  举报
-->
查看放大的地图   |   获取路线