这是一道KM模板题,函数部分都是一样的,只是建图不同。这里的建图是如果01矩阵中数字是1的话,那么第i条鱼攻击第j条鱼时,所产生的鱼卵数是第i条鱼和第j条鱼的异或值;
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define N 110
using namespace std;
int link[N],mat[N][N],vx[N],vy[N],lx[N],ly[N];
int n;
int dfs(int t)
{
int i;
vx[t]=1;
for(i=1; i<=n; i++)
{
if(vy[i]==0&&lx[t]+ly[i]==mat[t][i])
{
vy[i]=1;
if(link[i]==-1||dfs(link[i]))
{
link[i]=t;
return 1;
}
}
}
return 0;
}
void KM()
{
int i,j,t,k;
memset(lx,0,sizeof(lx));
memset(ly,0,sizeof(ly));
for(i=1; i<=n; i++)
for(j=1; j<=n; j++)
lx[i]=max(lx[i],mat[i][j]);
for(i=1; i<=n; i++)
{
while(1)
{
memset(vx,0,sizeof(vx));
memset(vy,0,sizeof(vy));
if(dfs(i))
break;
else
{
t=9999999;
for(k=1; k<=n; k++)
if(vx[k])
for(j=1; j<=n; j++)
if(vy[j]==0&&lx[k]+ly[j]-mat[k][j]<t)
t=lx[k]+ly[j]-mat[k][j];
for(j=1; j<=n; j++)
{
if(vx[j])
lx[j]-=t;
if(vy[j])
ly[j]+=t;
}
}
}
}
}
int main()
{
int i,j,ans,a[N];
char ch;
while(scanf("%d",&n),n!=0)
{
memset(link,-1,sizeof(link));
memset(mat,0,sizeof(mat));//注意初始化mat数组,很重要,不然会WA,因为如果i不能攻击j的话,权值是零;
for(i=1; i<=n; i++)
scanf("%d",&a[i]);
for(i=1; i<=n; i++)
for(j=1; j<=n; j++)
{
scanf(" %c",&ch);
if(ch=='1')
mat[i][j]=(a[i]^a[j]);
}
KM();
ans=0;
for(i=1; i<=n; i++)
ans+=mat[link[i]][i];
printf("%d\n",ans);
}
return 0;
}