八中公司_二分图带权最大匹配模板题
Problem S: 八中公司
Description
小W在八中开了一个兼职中心。现在他手下有N个工人。每个工人有N个工作可以选择,于是每个人做每个工作的效率是不一样的。做为CEO的小W的任务就是给每个人分配一个工作,保证所有人效率之和是最大的。N<=200
Input
第一行给出数字N
接下来N行N列,代表每个人工作的效率。
Output
一个数字,代表最大效率之和
Sample Input
4
62 41 86 94
73 58 11 12
69 93 89 88
81 40 69 13
Sample Output
329
思路:
二分图带权最大匹配裸题
二分图带权最大匹配不会的看这里https://blog.csdn.net/x_y_q_/article/details/51927054
具体见代码
输入的w[i][j]就相当于第i个女生对第j个男生的期望值
//附上蒟蒻代码
1 #include <bits/stdc++.h> 2 using namespace std; 3 int n,w[1001][1001]; 4 int lx[1001],ly[1001],matched[1001],slack[1001]; 5 bool s[1001],t[1001]; 6 bool match(int i) {//匈牙利算法 7 s[i]=1; //第i个女生打上标记 8 for(int j=1; j<=n; j++) { 9 int cnt=lx[i]+ly[j]-w[i][j];//求出gap值 10 if(cnt==0&&!t[j]) { //如果gap值为0,且第J个男生在本轮没有被占用 11 t[j]=1;//打上标记 12 if(!matched[j]||match(matched[j])) 13 //如果男生J从来没有被许配,或者被许配的对象可以向后调整的话 14 { 15 matched[j]=i; 16 //标记男生j被第i个女生占有 17 return 1; 18 } 19 } else 20 slack[j]=min(slack[j],cnt); 21 } 22 return false; 23 } 24 void update() { 25 int a=INT_MAX; 26 for(int i=1; i<=n; i++) 27 if(!t[i])//没有被选到(匹配失败了) 28 a=min(a,slack[i]);//求出最少要减(加)的期望值 29 for(int i=1; i<=n; i++) { 30 if(s[i])lx[i]-=a;//女生降低期望值 31 if(t[i])ly[i]+=a;//男生增加期望值 32 } 33 } 34 void km() { 35 for(int i=1; i<=n; i++) 36 for(int j=1; j<=n; j++) 37 lx[i]=max(lx[i],w[i][j]);//求出女生最高期望值是多少 38 for(int i=1; i<=n; i++) { 39 memset(slack,0x3f,sizeof(slack)); 40 while(1) 41 //整体采用贪心算法,保证每次能使一个女生匹配成功 42 { 43 memset(s,0,sizeof(s)); 44 memset(t,0,sizeof(t));//注意每一轮s,t都要清空 45 if(match(i)) 46 break; 47 else 48 //调整标顶值 49 update(); 50 } 51 } 52 } 53 int main() { 54 scanf("%d",&n); 55 for(int i=1; i<=n; i++) 56 for(int j=1; j<=n; j++) 57 scanf("%d",&w[i][j]); 58 km(); 59 int ans=0; 60 for(int i=1; i<=n; i++) 61 ans+=lx[i]+ly[i]; 62 printf("%d",ans); 63 return 0; 64 }