POJ2513 并查集+hash+欧拉回路

网上盛传这题非常好,可以用多种方法解。

哎,这是第一次遇到并查集的题目,下面的代码基本上都是看着别人的代码写的,算是打酱油了。

思路:一个棒子两头有颜色,类比为欧拉回路,每个颜色为一个地点,每个棒子是一个边路。

欧拉通路要求:1.图是连通的。2.图中只有0个或2个节点的度为奇数。

所以命题等价为:节点的入度为奇数的节点只有0个或者只有2个。

对节点(颜色)就采用hash。然后判断通路用并查集。

#include<iostream>
const int N=250005;
int color[N];
int father[N];
unsigned int makehash(char *p)
{
int key=1;
while(*p)key=(key*29+(*p++)-'a')%9991;
return key;
}
int find(int x)
{
int root=x,tmp;
while(father[root]>=0)root=father[root];
/*while(x!=root)
    {
        tmp=father[x];
        father[x]=root;
        x=tmp;
    }*/
return root;
}
void Union(int root1 ,int root2)
{
int sum=father[root1]+father[root2];
if(father[root1]>father[root2])
{
father[root1]=root2;
father[root2]=sum;
}
else
{
father[root2]=root1;
father[root1]=sum;
}
}
int main()
{
//freopen("C:\\Users\\wuyanyisb\\Desktop\\1.txt","r",stdin);
int n=0;
memset(father,-1,sizeof(father));
int root1,root2,a,b;
char s1[12],s2[12];
while(scanf("%s%s",s1,s2)!=EOF)
{
a=makehash(s1);
b=makehash(s2);
color[a]++;
color[b]++;
root1=find(a);
root2=find(b);
if(root1!=root2)
Union(root1,root2);
}
int root=1,num=0;
for(int i=0;i<N;i++)
{
if(color[i]>0)
{
if(color[i]%2)
{
num++;
if(num>2)
{
printf("Impossible\n");
return 0;
}
}
if(root==1)
root=find(i);
else if(root!=find(i))
{
printf("Impossible\n");
return 0;
}
}
}
printf("Possible\n");
system("pause");
return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值