输入多组数据,每组数据两种颜色,表示一根木头两端的颜色,现在要将这些木头相连,要求相连部分颜色相同,问能否全部连通
提示
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; }
并查集+欧拉回路+字典树 Colored Sticks POJ 2513
时间: 2024-12-23 23:31:15