UVA11383 Golden Tiger Claw —— KM算法

题目链接:https://vjudge.net/problem/UVA-11383

 

 

 

 

题解:

根据KM()算法,标杆满足:l(x) + l(y) >= w(x, y)

当求完最大权匹配之后,所有标杆在满足:l(x) + l(y) >= w(x, y) 的条件下,和最小。

 

 

代码如下:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 typedef long long LL;
 4 const int INF = 2e9;
 5 const LL LNF = 9e18;
 6 const int mod = 1e9+7;
 7 const int MAXN = 500+10;
 8 
 9 int nx, ny;
10 int g[MAXN][MAXN], linker[MAXN], lx[MAXN], ly[MAXN], slack[MAXN];
11 bool visx[MAXN], visy[MAXN];
12 
13 bool DFS(int x)
14 {
15     visx[x] = true;
16     for(int y = 1; y<=ny; y++)
17     {
18         if(visy[y]) continue;
19         int tmp = lx[x] + ly[y] - g[x][y];
20         if(tmp==0)
21         {
22             visy[y] = true;
23             if(linker[y]==-1 || DFS(linker[y]))
24             {
25                 linker[y] = x;
26                 return true;
27             }
28         }
29         else
30             slack[y] = min(slack[y], tmp);
31     }
32     return false;
33 }
34 
35 void KM()
36 {
37     memset(linker, -1, sizeof(linker));
38     memset(ly, 0, sizeof(ly));
39     for(int i = 1; i<=nx; i++)
40     {
41         lx[i] = -INF;
42         for(int j = 1; j<=ny; j++)
43             lx[i] = max(lx[i], g[i][j]);
44     }
45 
46     for(int x = 1; x<=nx; x++)
47     {
48         for(int i = 1; i<=ny; i++)
49             slack[i] = INF;
50         while(true)
51         {
52             memset(visx, 0, sizeof(visx));
53             memset(visy, 0, sizeof(visy));
54 
55             if(DFS(x)) break;
56             int d = INF;
57             for(int i = 1; i<=ny; i++)
58                 if(!visy[i])
59                     d = min(d, slack[i]);
60 
61             for(int i = 1; i<=nx; i++)
62                 if(visx[i])
63                     lx[i] -= d;
64             for(int i = 1; i<=ny; i++)
65             {
66                 if(visy[i]) ly[i] += d;
67                 else slack[i] -= d;
68             }
69         }
70     }
71 }
72 
73 int main()
74 {
75     int n;
76     while(scanf("%d",&n)!=EOF)
77     {
78         nx = ny = n;
79         for(int i = 1; i<=nx; i++)
80         for(int j = 1; j<=ny; j++)
81             scanf("%d",&g[i][j]);
82 
83         KM();
84         int sum = 0;
85         for(int i = 1; i<=nx; i++) printf("%d ", lx[i]), sum += lx[i];
86         printf("\n");
87         for(int i = 1; i<=ny; i++) printf("%d ", ly[i]), sum += ly[i];
88         printf("\n");
89         printf("%d\n", sum);
90     }
91 }
View Code

 

posted on 2017-11-14 13:30  h_z_cong  阅读(185)  评论(0编辑  收藏  举报

导航