题目链接:点击打开链接
给木棍两段涂上颜色,两根木棍相接部分颜色必须相同,给出木棍两端颜色,求是否可以把所有木棍连起来。(题意我编的)
并查集和欧拉路判断:总度数为奇的点不存在或只有两个的连通图。
//73372K 1282MS
//C++ 1247B
#include <cstring>
#include <cstdio>
#define N 555555
int degree[N],s[N],n;
struct node
{
int id;
node *next[27];
node() //结构体内部函数完成初始化
{
id=0;
memset(next,0,sizeof(next));
}
};
struct node *root=0;
int hashs(char *x)
{
struct node *p=root,*h;
for(int i=0;x[i];i++)
{
int y=x[i]-'a';
if(p->next[y]==0)
{
h=new node;
p->next[y]=h;
}
p=p->next[y];
}
if(p->id==0) //总感觉这个初始化已经很扣了然而还是很慢
{
p->id=++n;
s[p->id]=p->id;
}
return p->id;
}
int findset(int x)
{
if(x!=s[x]) //之前写成while了,无限超时,一脸蒙蔽
return s[x]=findset(s[x]);
return s[x];
}
bool judge()
{
int num=0,l;
l=findset(1);
for(int i=1;i<=n;i++)
{
if(degree[i]&1)
num++;
if(num>2) return false; //剪剪枝
if(findset(i)!=l)
return false;
}
if(num==1)
return false;
return true;
}
int main()
{
int i,j;
root=new node;
char str[22],str1[22];
while(~scanf("%s %s",str,str1))
{
i=hashs(str);
j=hashs(str1);
degree[i]++;
degree[j]++;
s[findset(j)]=findset(i);
}
if(judge())
printf("Possible\n");
else
printf("Impossible\n");
return 0;
}