hdu 3395 Special Fish(二分图)

来源:互联网 发布:淘宝退货支付运费 编辑:程序博客网 时间:2024/05/26 07:30

貌似有点坑爹哦,我数组开到1010,结果超时了,改到101就过了!闷!!!

在题目中出现”XOR“,读题时没搞懂,后来百度一下,原来“异或”,我囧~~~~

一道简单的二分图!!!

附摘自百度的异或介绍:

/*

定义:

Exclusive OR(异-或运算、模2和)
异或(xor)是一个数学运算符。它应用于逻辑运算。异或符号为“^”。其运算法则为:
a^b=(a' and b) or (a and b')(a'为非a)。
a^b=a' b + ab'(a'为a取反)(b' 为b取反)。
真异或假的结果是真,假异或真的结果也是真,真异或真的结果是假,假异或假的结果是假。就是说两个值不相同,则异或结果为真。反之,为假。 不同为1,相同为0.
异或也叫半加运算,其运算法则相当于不带进位的二进制加法:二进制下用1表示真,0表示假,则异或的运算法则为:0异或0=0,1异或0=1,0异或1=1,1异或1=0(同为0,异为1),这些法则与加法是相同的,只是不带进位。
异或略称为XOR、EOR、EX-OR
程序中有三种演算子:XOR、xor、 ^。
使用方法如下
z = x ^ y;
z = x xor y;
运算法则:
1. a ^ a = 0
2. a ^ b = b ^ a
3. a ^ b ^ c = a ^ (b ^ c) = (a ^ b) ^ c;
4. d = a ^ b ^ c 可以推出 a = d ^ b ^ c.
5. a ^ b ^ a = b.
6.若x是二进制数0101,y是二进制数1011
则x^y=1110
只有在两个比较的位不同时其结果是1,否则结果为0
即“相同为0,不同为1”!
输入
运算符
输入
结果
1
^
0
1
1
^
1
0
0
^
0
0
0
^
1
1

*/

#include<stdio.h>

#include<string.h>


#define max(a,b) a>b?a:b
#define min(a,b) a<b?a:b
#define inf 100000000
#define N 101


int map[N][N],lx[N],ly[N],match[N],sx[N],sy[N];
int n;


int find(int k)
{
int i;
sx[k]=1;
for(i=1;i<=n;i++)
{
if(map[k][i]==lx[k]+ly[i]&&sy[i]==0)
{
sy[i]=1;
if(match[i]==0||find(match[i])==1)
{
match[i]=k;
return 1;
}
}
}
return 0;
}


int KM()
{
int i,j,k,ans=0;
memset(match,0,sizeof(match));
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],map[i][j]);
for(i=1;i<=n;i++)
{
while(1)
{
memset(sx,0,sizeof(sx));
memset(sy,0,sizeof(sy));
if(find(i))break;
else
{
int a=inf;
for(j=1;j<=n;j++)
if(sx[j])
for(k=1;k<=n;k++)
if(!sy[k])
a=min(a,lx[j]+ly[k]-map[j][k]);
for(j=1;j<=n;j++)
{
if(sx[j])lx[j]-=a;
if(sy[j])ly[j]+=a;
}
}
}
}
for(i=1;i<=n;i++)
{
ans+=map[match[i]][i];
}
return ans;
}


int main()
{
int i,j,b[200];
char aa[200][200];
while(scanf("%d",&n),n)
{
memset(map,0,sizeof(map));
for(i=1;i<=n;i++)
scanf("%d",&b[i]);
for(i=1;i<=n;i++)
{
scanf("%s",aa[i]+1);
for(j=1;j<=n;j++)
if(aa[i][j]=='1')
{
map[i][j]=b[i]^b[j];
}
}
printf("%d\n",KM());
}
return 0;
}
/*
#include<stdio.h>
int main()
{
int i,j;
for(i=1;i<=10;i++)
{
for(j=1;j<=10;j++)
printf("%d ",i^j);
printf("\n");
}

return 0;

}*/

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3395

原创粉丝点击