poj-2513 Colored Sticks (Trie+欧拉回路+并查集)
题目链接:http://poj.org/problem?id=2513
思路:1.Trie保存颜色字符串
2.并查集判断是否联通
3.欧拉回路判断是否能连接成一条线(或者说一笔画完)
代码(AC):
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 #define maxn 500008 7 int N=0; 8 int color_count[maxn]; 9 int deep[maxn]; 10 int father[maxn]; 11 12 struct trie{ 13 int color; 14 trie *kid[26]; 15 trie() 16 { 17 color=0; 18 for(int i=0;i<26;i++) 19 kid[i]=NULL; 20 } 21 }*root; 22 23 int insert_trie(trie *p,char str[]) 24 { 25 for(int i=0;i<strlen(str);i++) 26 { 27 int id=str[i]-'a'; 28 if(p->kid[id]==NULL) 29 { 30 p->kid[id]=new trie; 31 } 32 p=p->kid[id]; 33 34 if(i==strlen(str)-1) 35 { 36 if(p->color==0) 37 p->color=++N; 38 color_count[p->color]++; 39 return p->color; 40 } 41 } 42 return 0; 43 } 44 45 void union_point(int x,int y) 46 { 47 if(deep[x]>deep[y]) 48 father[y]=father[x]; 49 else if(deep[x]<deep[y]) 50 father[x]=father[y]; 51 else 52 { 53 father[y]=father[x]; 54 deep[x]++; 55 } 56 } 57 58 int find_father(int x) 59 { 60 if(x!=father[x]) 61 father[x]=find_father(father[x]); 62 else 63 return father[x]; 64 } 65 66 bool is_connected() 67 { 68 for(int i=2;i<=N;i++) 69 if(find_father(i)!=find_father(i-1)) 70 return false; 71 return true; 72 } 73 74 bool is_legal() 75 { 76 if(!is_connected()) 77 return false; 78 int temp=0; 79 for(int i=1;i<=N;i++) 80 { 81 if(color_count[i]%2!=0) 82 temp++; 83 if(temp>2) 84 return false; 85 } 86 return true; 87 } 88 89 void init() 90 { 91 for(int i=0;i<maxn;i++) 92 { 93 father[i]=i; 94 deep[i]=0; 95 } 96 } 97 98 void read() 99 { 100 char first[11],second[11]; 101 memset(color_count,0,sizeof(color_count)); 102 init(); 103 N=0; 104 root=new trie; 105 while(~scanf("%s%s",first,second)) 106 { 107 int x=insert_trie(root,first); 108 int y=insert_trie(root,second); 109 union_point(x,y); 110 } 111 } 112 113 int main() 114 { 115 init(); 116 read(); 117 if(is_legal()) 118 printf("Possible\n"); 119 else 120 printf("Impossible\n"); 121 return 0; 122 }