hdu 2255 KM better off big money Best Match algorithm

Perfect match, X each has a matching set, collection or Y are each match.

Best match, and the maximum weight of a complete match as the best match.

To add some edge to the right side of zero, the maximum weight will be able to match and best match to unify.

KM algorithmic process, we assume that X does not exceed the size of the set of Y collection.

X start point of each set to a tag, which is the maximum value of the right adjacent Collage, Y 0 is set for each point labels.

If the two endpoints of an edge of the label and to the right side, the side that this article is available. Every time we make available the edge of the Hungarian algorithm, if a match is found the side exit, trying to find a point of matching edges. Otherwise, all tag points set X will match the process through a reduced d, through all tag points to add a set of Y d. Then re-do Hungarian algorithm available on the edge. D Obviously, this should be just the matching process, and the smallest difference between the labels and the right side.

KM core algorithm is that we pass through to X rendezvous increase d, to a collection point reduction through Y d. After making two endpoints of the edge, is still available. Two did not end after the side, still retains its original state. After collection of endpoints X, Y set not after the endpoint is unavailable side, now becomes smaller and the label, may be available. No demerit set X end, through a set of endpoints unavailable Y side, now becomes large and the label, is still unavailable. So create a new right side and most likely successful match.

 1 #include <cstdio>
 2 #include <algorithm>
 3 using namespace std;
 4 const int inf = 1000000000;
 5 int n,ans,mind;
 6 int mp[310][310],lbx[310],lby[310],mth[310];
 7 bool visx[310],visy[310];
 8 bool find(int x)
 9 {
10     visx[x] = true;
11     for (int i = 1;i <= n;i++)
12     {
13         if (visy[i])
14             continue;
15         int t = lbx[x] + lby[i] - mp[x][i];
16         if (t == 0)
17         {
18             visy[i] = true;
19             if (mth[i] == 0 || find(mth[i]))
20             {
21                 mth[i] = x;
22                 return true;
23             }
24         }else25             mind = min(mind,t);
26     }
27     return false;
28 }
29 void KM()
30 {
31     for (int i = 1;i <= n;i++)
32     {
33         lbx[i] = 0;
34         for (int j = 1;j <= n;j++)
35             lbx[i] = max(lbx[i],mp[i][j]);
36     }
37     for (int i = 1;i <= n;i++)
38     {
39         lby[i] = 0;
40         mth[i] = 0;
41     }
42     for (int i = 1;i <= n;i++)
43     {
44         for (;;)
45         {
46             for (int j = 1;j <= n;j++)
47                 visx[j] = 0;
48             for (int j = 1;j <= n;j++)
49                 visy[j] = 0;
50             mind = inf;
51             if (find(i))
52                 break;
53             for (int j = 1;j <= n;j++)
54                 if (visx[j]) 
55                     lbx[j] -= mind;
56             for (int j = 1;j <= n;j++)
57                 if (visy[j]) 
58                     lby[j] += mind;
59         }
60     }
61 }
62 int main()
63 {
64     for (;scanf("%d",&n) > 0;)
65     {
66         for (int i = 1;i <= n;i++)
67             for (int j = 1;j <= n;j++)
68                 scanf("%d",&mp[i][j]);
69         KM();
70         ans = 0;
71         for (int i = 1;i <= n;i++)
72             if (mth[i] != 0)
73                 ans += mp[mth[i]][i];
74         printf("%d\n",ans);
75     }
76     return 0;
77 }

 

 

Guess you like

Origin www.cnblogs.com/iat14/p/11817996.html