码迷,mamicode.com
首页 > 编程语言 > 详细

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

时间:2020-05-11 18:24:33      阅读:63      评论:0      收藏:0      [点我收藏+]

标签:tom   none   eof   ||   ==   inline   stream   class   nbsp   

题目连接: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("\n");
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("\n%d\n",ans);
83     }
84     return 0;
85 }
View Code

 

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

标签:tom   none   eof   ||   ==   inline   stream   class   nbsp   

原文地址:https://www.cnblogs.com/DZN2004/p/12870740.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!