标签: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 }
UVA11383 Golden Tiger Claw——二分图(KM算法)
标签:tom none eof || == inline stream class nbsp
原文地址:https://www.cnblogs.com/DZN2004/p/12870740.html