输入多组数据,每组数据两种颜色,表示一根木头两端的颜色,现在要将这些木头相连,要求相连部分颜色相同,问能否全部连通
提示
1)一个要判断所有的木头是否在一个集合中,即是否能相连
2)判断一种颜色出现的数量
3)一棵树如果只有0或2个点出现次数为奇数,则树可以一笔画成
#include <stdio.h>
#include <string.h>
#define maxn 500005
int tot;
int f[maxn];
int num[maxn];
struct trie
{
trie *next[30];
int id;
trie()
{
for(int i=0;i<30;i++)
next[i]=NULL;
id=0;
}
};
trie *root;
int find(int i)
{
if(i==f[i])
return f[i];
f[i]=find(f[i]);
return f[i];
}
int build(char *str) //建立字典树
{
int len=strlen(str);
trie *p=root;
for(int i=0;i<len;i++)
{
int id=str[i]-'a';
if(p->next[id]==NULL)
p->next[id]=new trie;
p=p->next[id];
}
if(p->id==0)
p->id=tot++;
return p->id;
}
int main()
{
char str1[50];
char str2[50];
int a,b;
int fr,ed;
int i;
for(i=0;i<maxn;i++)
{
f[i]=i;
num[i]=0;
}
tot=1;
int tt=0,ff=0;
root=new trie;
while(scanf("%s%s",str1,str2)!=-1)
{
a=build(str1);
b=build(str2);
fr=find(a);
ed=find(b);
if(fr!=ed)
f[fr]=ed; //集合
num[a]++; //统计出现次数
num[b]++;
}
for(i=1;i<tot;i++)
if(num[i]%2==1)
tt++;
for(i=1;i<tot;i++)
if(f[i]==i)
ff++;
if(((tt==0)||(tt==2))&&(ff==1||ff==0))
printf("Possible\n");
else
printf("Impossible\n");
return 0;
}