HDU 3395 Special Fish【最大权匹配】

题意:最大权匹配

分析:最大全匹配

代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 using namespace std;
 5 
 6 const int maxn = 105;
 7 const int INF = 2000000000;
 8 
 9 bool Sx[maxn], Sy[maxn];
10 int Lx[maxn], Ly[maxn];
11 int Link[maxn];
12 int W[maxn][maxn];
13 int n, m;
14 
15 bool Find(int i) {
16     Sx[i] = true;
17     for(int j = 1; j <= m; j++) {
18         if(!Sy[j] && Lx[i] + Ly[j] == W[i][j]) {
19             Sy[j] = true;
20             if(Link[j] == 0 || Find(Link[j])) {
21                 Link[j] = i;
22                 return true;
23             }
24         }
25     }
26     return false;
27 }
28 
29 int KM() {
30     for(int i = 1; i <= n;i++) {
31         Lx[i] = 0;
32         for(int j = 1; j <= m; j++) {
33             Lx[i] = max(Lx[i], W[i][j]);
34         }
35     }
36     memset(Ly, 0, sizeof(Ly));
37     memset(Link, 0, sizeof(Link));
38     for(int v = 1; v <= n; v++) {
39         memset(Sx, 0, sizeof(Sx));
40         memset(Sy, 0, sizeof(Sy));
41         while(1) {
42             if(Find(v)) break;
43             int dmin = INF;
44             for(int i = 1; i <= n; i++) {
45                 if(Sx[i]) {
46                     for(int j = 1; j <= m; j++) {
47                         if(!Sy[j] && Lx[i] + Ly[j] - W[i][j] < dmin) {
48                             dmin = Lx[i] + Ly[j] - W[i][j];
49                         }
50                     }
51                 }
52             }
53             for(int i = 1; i <= n; i++) {
54                 if(Sx[i]) {
55                     Lx[i] -= dmin;
56                     Sx[i] = 0;
57                 }
58             }
59             for(int i = 1; i <= m; i++) {
60                 if(Sy[i]) {
61                     Ly[i] += dmin;
62                     Sy[i] = 0;
63                 }
64             }
65         }
66     }
67     int sum = 0;
68     for(int i = 1; i <= n; i++) {
69         sum += W[Link[i]][i];
70     }
71     return sum;
72 }
73 
74 int val[maxn];
75 char mat[maxn][maxn];
76 int main() {
77     while(scanf("%d",&n) && n) {
78         memset(W, 0, sizeof(W));
79         for(int i = 1; i <= n; i++) {
80             scanf("%d",&val[i]);
81         }
82         for(int i = 1; i <= n; i++) {
83             scanf("%s",mat[i]);
84         }
85         for(int i = 1; i <= n; i++) {
86             for(int j = 0; j < n; j++) {
87                 if(i == j + 1) continue;
88                 if(mat[i][j] == '1') {
89                     W[i][j + 1] = val[i] ^ val[j + 1];
90                 }
91             }
92         }
93         m = n;
94         printf("%d\n",KM());
95     }
96     return 0;
97 }
View Code

 

posted @ 2014-08-26 23:05  悠悠我心。  阅读(153)  评论(0编辑  收藏  举报