POJ 2513 Colored Sticks (欧拉回路 + 字典树 +并查集)
Colored Sticks
Description You are given a bunch of wooden sticks. Each endpoint of each stick is colored with some color. Is it possible to align the sticks in a straight line such that the colors of the endpoints that touch are of the same color?
Input Input is a sequence of lines, each line contains two words, separated by spaces, giving the colors of the endpoints of one stick. A word is a sequence of lowercase letters no longer than 10 characters. There is no more than 250000 sticks.
Output If the sticks can be aligned in the desired way, output a single line saying Possible, otherwise output Impossible.
Sample Input blue red red violet cyan blue blue magenta magenta cyan Sample Output Possible Hint Huge input,scanf is recommended.
Source |
详细解释:http://blog.csdn.net/lyy289065406/article/details/6647445
#include<iostream> #include<cstdio> #include<cstring> #include<vector> using namespace std; struct Trie{ int x; Trie *next[26]; }*root,memory[5100000]; int deg[5100000],father[510000],cnt,tot; Trie *create(){ Trie *p=&memory[cnt++]; for(int i=0;i<26;i++) p->next[i]=NULL; return p; } void InsertTrie(char *str,int x){ Trie *loc=root; for(int i=0;str[i]!='\0';i++){ int id=str[i]-'a'; if(loc->next[id]==NULL) loc->next[id]=create(); loc=loc->next[id]; } loc->x=x; } int SearchTrie(char *str){ Trie *loc=root; for(int i=0;str[i]!='\0';i++){ int id=str[i]-'a'; if(loc->next[id]==NULL) return 0; loc=loc->next[id]; } return loc->x; } void init(){ for(int i=1;i<=501000;i++) father[i]=i; memset(deg,0,sizeof(deg)); cnt=0; tot=0; } int findSet(int x){ if(x!=father[x]){ father[x]=findSet(father[x]); } return father[x]; } int judge(){ //判断是否满足欧拉 int odd=0; for(int i=1;i<=tot;i++) if(deg[i]%2==1) odd++; if(odd!=0 && odd!=2) return 0; int k=findSet(1); for(int i=2;i<=tot;i++) if(k!=findSet(i)) return 0; return 1; } int main(){ //freopen("input.txt","r",stdin); char s1[15],s2[15]; init(); root=create(); while(~scanf("%s%s",s1,s2)){ int x=SearchTrie(s1); //映射求编号速度太慢 int y=SearchTrie(s2); //用字典树来求编号 if(x==0) InsertTrie(s1,x=++tot); if(y==0) InsertTrie(s2,y=++tot); deg[x]++; deg[y]++; int fx=findSet(x); int fy=findSet(y); if(fx!=fy) father[fx]=fy; } if(judge()) printf("Possible\n"); else printf("Impossible\n"); return 0; }