題目鏈接:點擊打開鏈接
給木棍兩段塗上顏色,兩根木棍相接部分顏色必須相同,給出木棍兩端顏色,求是否可以把所有木棍連起來。(題意我編的)
並查集和歐拉路判斷:總度數爲奇的點不存在或只有兩個的連通圖。
//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;
}