UVA11383 Golden Tiger Claw——二分图(KM算法)

Posted dzn2004

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVA11383 Golden Tiger Claw——二分图(KM算法)相关的知识,希望对你有一定的参考价值。

题目连接:https://www.luogu.com.cn/problem/UVA11383

下面是题解:

我们仔细一想就会发现这道题其实是一个二分图最大匹配的板子

我们可以把这道题想象成将男生和女生之间两两配对,使他们的好感度最大

我们把矩阵中的元素a[x][y]

看成女生和男生之间的好感度,跑一个KM算法

因为KM算法会维护eboy[x]+egirl[y]>=Ai[y][x]

所以最后的结果就是我们想要的

确实挺简单,但是注意代码细节:

技术图片
 1 #include <cstdio>
 2 #include <algorithm>
 3 #include <cstring>
 4 #include <iostream>
 5 #define ll long long 
 6 using namespace std;
 7 const int maxn=510;
 8 int Ai[maxn][maxn],match[maxn],sta[maxn];
 9 int egirl[maxn],eboy[maxn];
10 bool vgirl[maxn],vboy[maxn];
11 int n;
12 bool DFS(int girl){
13     vgirl[girl]=1;
14     for(int boy=1;boy<=n;boy++){
15         if(vboy[boy]) continue;
16         int gap=egirl[girl]+eboy[boy]-Ai[girl][boy];
17         if(gap==0){
18             vboy[boy]=1;
19             if(match[boy]==-1 || DFS(match[boy])){
20                 match[boy]=girl;
21                 return 1;
22             }
23         } else {
24             sta[boy]=min(sta[boy],gap);
25         }
26     }
27     return 0;
28 }
29 void KM(){
30     memset(match,-1,sizeof(match));
31     memset(eboy,0,sizeof(eboy));
32     for(int i=1;i<=n;i++){
33         egirl[i]=Ai[i][1];
34         for(int j=2;j<=n;j++){
35             egirl[i]=max(Ai[i][j],egirl[i]);
36         }
37     }
38     for(int i=1;i<=n;i++){
39         memset(sta,0x3f,sizeof(sta));
40         while(1){
41             memset(vboy,0,sizeof(vboy));
42             memset(vgirl,0,sizeof(vgirl));
43             if(DFS(i)) break;
44             int d=0x3f3f3f3f;
45             for(int j=1;j<=n;j++){
46                 if(!vboy[j]) d=min(d,sta[j]);
47             }
48             for(int j=1;j<=n;j++){
49                 if(vgirl[j]) egirl[j]-=d;
50                 if(vboy[j]) eboy[j]+=d;
51                 else sta[j]-=d;
52             }
53         }
54     }
55 }
56 int main(){
57     //freopen("a.in","r",stdin);
58     while(scanf("%d",&n)!=EOF){
59         memset(Ai,0,sizeof(Ai));
60         memset(egirl,0,sizeof(egirl));
61         memset(eboy,0,sizeof(eboy));
62         memset(vgirl,0,sizeof(vgirl));
63         memset(vboy,0,sizeof(vboy));
64         memset(match,0x3f,sizeof(match));
65         memset(sta,-1,sizeof(sta));
66         for(int i=1;i<=n;i++)
67             for(int j=1;j<=n;j++)
68                 scanf("%d",&Ai[i][j]);
69         KM();
70         int ans=0;
71         for(int i=1;i<=n;i++){
72             if(i==1) printf("%d",egirl[i]);
73             else printf(" %d",egirl[i]);
74             ans+=egirl[i];
75         }
76         printf("
");
77         for(int i=1;i<=n;i++){
78             if(i==1) printf("%d",eboy[i]);
79             else printf(" %d",eboy[i]);
80             ans+=eboy[i];
81         }
82         printf("
%d
",ans);
83     }
84     return 0;
85 }
View Code

 

以上是关于UVA11383 Golden Tiger Claw——二分图(KM算法)的主要内容,如果未能解决你的问题,请参考以下文章

UVA 11383 Golden Tiger Claw 题解

UVA11383 Golden Tiger Claw——二分图(KM算法)

UVA11383 Golden Tiger Claw——二分图(KM算法)

UVA11383 Golden Tiger Claw

UVA11383 Golden Tiger Claw

Golden Tiger Claw (KM算法)