HDU 2255 二分图最佳匹配 模板题

 题目大意:

给定每一个人能支付的房子价值,每个人最多且必须拥有一套房子,问最后分配房子可得到的最大收益

抄了个别人的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
" , ans);
77     }
78     return 0;
79 }
原文地址:https://www.cnblogs.com/CSU3901130321/p/4710924.html