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;
}


 

 

posted on 2013-07-27 20:22  you Richer  阅读(189)  评论(0编辑  收藏  举报