题目大意:
给定每一个人能支付的房子价值,每个人最多且必须拥有一套房子,问最后分配房子可得到的最大收益
抄了个别人的KM模板,就这样了。。。
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 using namespace std; 6 #define N 305 7 const int INF = 0x7fffffff; 8 int n , nx , ny; 9 int slack[N] , lx[N] , ly[N] , linker[N] , w[N][N] , visx[N] , visy[N]; 10 11 int dfs(int u) 12 { 13 visx[u] = 1; 14 for(int y=1 ; y<=ny ; y++){ 15 if(visy[y]) continue; 16 int tmp = lx[u]+ly[y]-w[u][y]; 17 if(tmp == 0){ 18 visy[y]=1; 19 if(linker[y]==-1 || dfs(linker[y])){ 20 linker[y]=u; 21 return 1; 22 } 23 } 24 else if(slack[y]>tmp) slack[y] = tmp; 25 } 26 return 0; 27 } 28 29 int KM() 30 { 31 memset(linker , -1 , sizeof(linker)); 32 memset(ly , 0 , sizeof(ly)); 33 //lx初始化为最大的边长 34 for(int i=1 ; i<=nx ; i++) 35 { 36 lx[i] = -INF; 37 for(int j=1 ; j<=ny ; j++) 38 lx[i] = max(lx[i] , w[i][j]); 39 } 40 for(int i=1 ; i<=nx ; i++){ 41 for(int j=1 ; j<=ny ; j++){ 42 slack[j] = INF; 43 } 44 while(true){ 45 memset(visx , 0 , sizeof(visx)); 46 memset(visy , 0 , sizeof(visy)); 47 if(dfs(i)) break; //若找不到增广路,就需要改变一下标号 48 int a = INF; 49 for(int k=1 ; k<=ny ; k++) 50 if(!visy[k]&&a>slack[k]) 51 a = slack[k]; 52 for(int k=1 ; k<=nx ; k++) 53 if(visx[k]) 54 lx[k]-=a; 55 for(int k=1 ; k<=nx ; k++) 56 if(visy[k]) ly[k]+=a; 57 else slack[k]-=a; 58 } 59 } 60 int res = 0; 61 for(int i=1 ; i<=ny ; i++) 62 if(linker[i]!=-1) 63 res+=w[linker[i]][i]; 64 return res; 65 } 66 67 int main() 68 { 69 // freopen("in.txt" , "r" , stdin); 70 while(~scanf("%d" , &n)) 71 { 72 for(int i=1 ; i<=n ; i++) 73 for(int j=1 ; j<=n ; j++) scanf("%d" , &w[i][j]); 74 nx = n , ny = n; 75 int ans = KM(); 76 printf("%d\n" , ans); 77 } 78 return 0; 79 }
我还在坚持,我还未达到我所想,梦~~一直在