您的位置:首页 > 其它

HDU 3395 Special Fish【最大权匹配】

2014-08-26 23:05 471 查看
题意:最大权匹配

分析:最大全匹配

代码:

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;

const int maxn = 105;
const int INF = 2000000000;

bool Sx[maxn], Sy[maxn];
int Lx[maxn], Ly[maxn];
int Link[maxn];
int W[maxn][maxn];
int n, m;

bool Find(int i) {
Sx[i] = true;
for(int j = 1; j <= m; j++) {
if(!Sy[j] && Lx[i] + Ly[j] == W[i][j]) {
Sy[j] = true;
if(Link[j] == 0 || Find(Link[j])) {
Link[j] = i;
return true;
}
}
}
return false;
}

int KM() {
for(int i = 1; i <= n;i++) {
Lx[i] = 0;
for(int j = 1; j <= m; j++) {
Lx[i] = max(Lx[i], W[i][j]);
}
}
memset(Ly, 0, sizeof(Ly));
memset(Link, 0, sizeof(Link));
for(int v = 1; v <= n; v++) {
memset(Sx, 0, sizeof(Sx));
memset(Sy, 0, sizeof(Sy));
while(1) {
if(Find(v)) break;
int dmin = INF;
for(int i = 1; i <= n; i++) {
if(Sx[i]) {
for(int j = 1; j <= m; j++) {
if(!Sy[j] && Lx[i] + Ly[j] - W[i][j] < dmin) {
dmin = Lx[i] + Ly[j] - W[i][j];
}
}
}
}
for(int i = 1; i <= n; i++) {
if(Sx[i]) {
Lx[i] -= dmin;
Sx[i] = 0;
}
}
for(int i = 1; i <= m; i++) {
if(Sy[i]) {
Ly[i] += dmin;
Sy[i] = 0;
}
}
}
}
int sum = 0;
for(int i = 1; i <= n; i++) {
sum += W[Link[i]][i];
}
return sum;
}

int val[maxn];
char mat[maxn][maxn];
int main() {
while(scanf("%d",&n) && n) {
memset(W, 0, sizeof(W));
for(int i = 1; i <= n; i++) {
scanf("%d",&val[i]);
}
for(int i = 1; i <= n; i++) {
scanf("%s",mat[i]);
}
for(int i = 1; i <= n; i++) {
for(int j = 0; j < n; j++) {
if(i == j + 1) continue;
if(mat[i][j] == '1') {
W[i][j + 1] = val[i] ^ val[j + 1];
}
}
}
m = n;
printf("%d\n",KM());
}
return 0;
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: