给出木棒的首尾颜色,看能不能连成一根。
考察并查集+字典树+哈希
Sample Input
blue red
red violet
cyan blue
blue magenta
magenta cyan
Sample Output
Possible
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
int degree[500010],fa[500010],id = 1;
struct node
{
int flag;
int id;
node* nxt[26];
node ()
{
for(int i=0;i<26;i++)
nxt[i]=NULL;
flag=0;
}
};
node* root;
int fid(int x)
{
if(fa[x] != x)
fa[x] = fid(fa[x]);//路径压缩;
return fa[x];
}
//字典树哈希
int Hash(char s[])
{
node *p = root;
for(int i = 0; s[i]; i++)
{
if(p->nxt[s[i]-'a'] == NULL)
p->nxt[s[i]-'a'] = new node();
p = p->nxt[s[i]-'a'];
}
if(p->flag != 1)
{
p->flag = 1;
p->id = id++;
}
return p->id;
}
int check()
{
int sum = 0;
int x = fid(1);
for(int i = 2; i < id; i++)
if(fid(i) != x)//没有共同祖先,图是不连通的,直接返回;
return 0;
for(int i = 1; i < id; i++)
{
if(degree[i]%2)
sum++;
}
if(sum == 0 || sum == 2)
return 1;//图是连通的并且奇度数是0或2,说明有欧拉路;
return 0;//图是连通的但奇度数不是0或2也不存在欧拉路;
}
int main()
{
memset(degree,0,sizeof(degree));
for(int i = 1; i <= 500000; i++)
fa[i] = i;//所有节点初始化为一棵树
char s1[12],s2[12];
int u,v;
root = new node();
while(scanf("%s %s",s1,s2) != EOF)
{
u = Hash(s1);
v = Hash(s2);
degree[u]++;
degree[v]++;
int x = fid(u);
int y = fid(v);
if(x != y)
fa[x] = y;
}
if(check()) printf("Possible\n");
else printf("Impossible\n");
return 0;
}