KM算法模板 hdu 2255

KM算法是在匹配是完备的情况下寻找最优匹配。

首先,先将范围定为最大的情况,如果最大的情况无法满足,就下降一个维度继续匹配。

直到匹配成功。

 1 #include<cstdio>
 2 #include<string.h>
 3 #include<algorithm>
 4 using namespace std;
 5 const int maxn=3e2+10;
 6 const int inf=0x3f3f3f3f;
 7 int G[maxn][maxn],n;
 8 int lx[maxn],ly[maxn];
 9 int match[maxn];
10 int visx[maxn],visy[maxn];
11 void init()
12 {
13     memset(match,0,sizeof(match));
14 }
15 int dfs(int k)
16 {
17     visx[k]=1;
18     for(int i=1;i<=n;i++){
19         if(!visy[i]&&G[k][i]==lx[k]+ly[i]){
20             visy[i]=1;
21             if(!match[i]||dfs(match[i])){
22                 match[i]=k;
23                 return 1;
24             }
25         }
26     }
27     return 0;
28 }
29 int KM()
30 {
31     for(int i=1;i<=n;i++){
32         lx[i]=-inf,ly[i]=0;
33         for(int j=1;j<=n;j++)
34             lx[i]=max(lx[i],G[i][j]);
35     }
36     for(int k=1;k<=n;k++){
37         while(1){
38             memset(visx,0,sizeof(visx));
39             memset(visy,0,sizeof(visy));
40             if(dfs(k)) break;
41             int mn=inf;
42 
43             for(int i=1;i<=n;i++) if(visx[i])
44             for(int j=1;j<=n;j++) if(!visy[j])
45             mn=min(mn,lx[i]+ly[j]-G[i][j]);
46             if(mn==inf) return -1;
47             for(int i=1;i<=n;i++) if(visx[i]) lx[i]-=mn;
48             for(int i=1;i<=n;i++) if(visy[i]) ly[i]+=mn;
49         }
50     }
51     int ans=0;
52     for(int i=1;i<=n;i++) if(match[i])
53     ans+=G[match[i]][i];
54     return ans;
55 }
56 int main()
57 {
58     while(scanf("%d",&n)!=EOF){
59         init();
60         for(int i=1;i<=n;i++)
61         for(int j=1;j<=n;j++)
62         scanf("%d",&G[i][j]);
63         printf("%d\n",KM());
64     }
65     return 0;
66 }

 

posted @ 2019-09-16 19:58  古比  阅读(160)  评论(0编辑  收藏  举报