题意是给你n条鱼,每条鱼有个值,每条鱼只能和一条自己认为可以的鱼交配,只能被一条鱼交配(一个是主动的一个是被动的)。生下的孩子的值是他们的异或和,求所有孩子和的最大值。
mp[i][j]=1表示i鱼认为j鱼可以交配。
没什么坑点,裸题。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
#define maxn 111
#define INF 111111111
#define left Left
int n;
char mp[maxn][maxn];
int a[maxn], w[maxn][maxn];
int lx[maxn], ly[maxn], left[maxn];
bool s[maxn], t[maxn];
bool match (int i) {
s[i] = 1;
for (int j = 1; j <= n; j++) if (lx[i]+ly[j] == w[i][j] && !t[j]) {
t[j] = 1;
if (!left[j] || match (left[j])) {
left[j] = i;
return 1;
}
}
return 0;
}
void update () {
int a = INF;
for (int i = 1; i <= n; i++) if (s[i])
for (int j = 1; j <= n; j++) if (!t[j])
a = min (a, lx[i]+ly[j]-w[i][j]);
for (int i = 1; i <= n; i++) {
if (s[i]) lx[i] -= a;
if (t[i]) ly[i] += a;
}
}
void km () {
for (int i = 1; i <= n; i++) {
left[i] = lx[i] = ly[i] = 0;
for (int j = 1; j <= n; j++)
lx[i] = max (lx[i], w[i][j]);
}
for (int i = 1; i <= n; i++) {
for (; ;) {
for (int j = 1; j <= n; j++) s[j] = t[j] = 0;
if (match (i))
break;
else update ();
}
}
}
int main () {
while (cin >> n && n) {
for (int i = 0; i < n; i++)
cin >> a[i];
for (int i = 0; i < n; i++)
cin >> mp[i];
memset (w, 0, sizeof w);
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (mp[i][j] == '1') {
w[i+1][j+1] = a[i]^a[j];
}
}
}
km ();
int ans = 0;
for (int i = 1; i <= n; i++) {
if (left[i]) {
ans += w[left[i]][i];
}
}
cout << ans << endl;
}
return 0;
}