hdu 3395

时间:2023-03-09 13:39:58
hdu 3395

KM裸题

每个鱼都认为自己是雄性,而且会攻击它认为是雌性的鱼,每个鱼只能被攻击一次,被攻击后会产卵(个数是给的两条鱼的值的异或运算)

#include<string.h>
#include<stdio.h>
#define N 110
#define inf 0x3fffffff
int map[N][N],lx[N],ly[N],sx[N],sy[N],n,d[N],cont[N],match[N];
int find(int x)
{
sx[x]=1;
for(int i=0;i<n;i++)
{
if(sy[i]==1)continue;
int temp=lx[x]+ly[i]-map[x][i];
if(temp==0)
{
sy[i]=1;
if(match[i]==-1||find(match[i])==1)
{
match[i]=x;
return 1;
}
}
else d[i]=d[i]>temp?temp:d[i];
}
return 0;
}
int KM()
{
int i,j,k,sum,min;
memset(match,-1,sizeof(match));
memset(ly,0,sizeof(ly));
for(i=0;i<n;i++)
{
lx[i]=map[i][0];
for(j=1;j<n;j++)
if(lx[i]<map[i][j])
lx[i]=map[i][j];
}
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
d[j]=inf;
while(1)
{
memset(sx,0,sizeof(sx));
memset(sy,0,sizeof(sy));
if(find(i)==1)break;
min=inf;
for(k=0;k<n;k++)
if(sy[k]==0&&min>d[k])
min=d[k];
for(j=0;j<n;j++)
{
if(sx[j]==1)lx[j]-=min;
if(sy[j]==1)ly[j]+=min;
}
}
}
sum=0;
for(i=0;i<n;i++)
sum+=map[match[i]][i];
return sum;
}
int main()
{
int i,j,k;
char str[110];
while(scanf("%d",&n)!=-1&&n)
{
for(i=0;i<n;i++)
scanf("%d",&cont[i]);
memset(map,0,sizeof(map));
for(i=0;i<n;i++)
{
scanf("%s",str);
for(j=0;j<n;j++)
if(str[j]=='1')
map[i][j]=cont[i]^cont[j];
}
k=KM();
printf("%d\n",k);
}
return 0;
}