并查集+欧拉回路+字典树 Colored Sticks POJ 2513

来源:互联网 发布:linux shell 捕获错误 编辑:程序博客网 时间:2024/06/05 06:26

输入多组数据,每组数据两种颜色,表示一根木头两端的颜色,现在要将这些木头相连,要求相连部分颜色相同,问能否全部连通

提示

1)一个要判断所有的木头是否在一个集合中,即是否能相连

2)判断一种颜色出现的数量

3)一棵树如果只有0或2个点出现次数为奇数,则树可以一笔画成

#include <stdio.h>#include <string.h>#define maxn 500005int 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");elseprintf("Impossible\n");return 0;}


0 0