首页 > 代码库 > HDU 3395 Special Fish【最大权匹配】

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

 

HDU 3395 Special Fish【最大权匹配】