P1559 运动员最佳匹配问题 KM算法

题目描述

羽毛球队有男女运动员各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。

输出格式

将计算出的男女双方竞赛优势的总和的最大值输出。

 

重新定义一个数组e【】【】来表示P【】【】Q【】【】的乘积

其余部分就全部都是KM模板了

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 //Data
 4 typedef long long ll;
 5 const int N=30;
 6 const int inf=0x3f3f3f3f;
 7 int n,e[N+7][N+7];
 8 int P[N][N],Q[N][N];
 9 //KM
10 int mb[N+7],vb[N+7],ka[N+7],kb[N+7],p[N+7],c[N+7];
11 int qf,qb,q[N+7];
12 void Bfs(int u){
13     int a,v=0,vl=0,d;
14     for(int i=1;i<=n;i++) p[i]=0,c[i]=inf;
15     mb[v]=u;
16     do {
17         a=mb[v],d=inf,vb[v]=1;
18         for(int b=1;b<=n;b++)if(!vb[b]){
19             if(c[b]>ka[a]+kb[b]-e[a][b])
20                 c[b]=ka[a]+kb[b]-e[a][b],p[b]=v;
21             if(c[b]<d) d=c[b],vl=b;
22         }
23         for(int b=0;b<=n;b++)
24             if(vb[b]) ka[mb[b]]-=d,kb[b]+=d;
25             else c[b]-=d;
26         v=vl;
27     } while(mb[v]);
28     while(v) mb[v]=mb[p[v]],v=p[v];
29 }
30 ll KM()
31 {
32     for(int i=1;i<=n;i++)
33         mb[i]=ka[i]=kb[i]=0;
34     for(int a=1;a<=n;a++){
35         for(int b=1;b<=n;b++) vb[b]=0;
36         Bfs(a);
37     }
38     ll res=0;
39     for(int b=1;b<=n;b++) res+=e[mb[b]][b];
40     return res;
41 }
42 
43 //Main
44 int main()
45 {
46 
47 
48 
49     scanf("%d",&n);
50     for(int i=1;i<=n;i++)
51     for(int j=1;j<=n;j++){
52         scanf("%d",&P[i][j]);
53     }
54     for(int i=1;i<=n;i++)
55     for(int j=1;j<=n;j++){
56         scanf("%d",&Q[i][j]);
57     }
58     for(int i=1;i<=n;i++)
59     for(int j=1;j<=n;j++){
60         e[i][j]=P[i][j]*Q[j][i];
61     }
62     printf("%lld\n",KM());
63     return 0;
64 }
View Code

 

posted @ 2020-07-16 21:34  古比  阅读(148)  评论(0编辑  收藏  举报