http://poj.org/problem?id=2513
73348K 1438MS C++ 1614B
解题思路:欧拉路的应用 要点 :1、判断连通性 2、欧拉路的判断(所有的节点的度为偶数或者只有两个奇数节点)
连通性的判断: 并查集-----由于本题的节点是字符串,,并不好处理,所以用Trie树来获得id。。然后 find 、unin 和普通并查集一样,。
连通性判断:并查集的祖先节点 ,,只有一个,若有多个即 不是连通图,也就不是欧拉路。。
1 #include <iostream> 2 #include<cstring> 3 #include<cstdio> 4 #define maxn 500005 5 using namespace std; 6 7 int f[maxn]; 8 int degree[maxn]; 9 int num; 10 struct node{ 11 int id; 12 struct node *next[27]; 13 node(){ 14 id =0; 15 memset(next,0,sizeof(next)); 16 } 17 }; 18 node *root = NULL; 19 20 int maketrie(char *s){//用trie树获得id,,,其实就是给每个节点一个编号。。。用一般的方法不好解决,,就只能用trie树了 21 node *p = root; 22 node *temp = NULL; 23 for(int i=0;i<strlen(s);i++){ 24 if(p->next[s[i]-'a']==NULL){ 25 temp = new node; 26 p->next[s[i]-'a']=temp; 27 } 28 p = p->next[s[i]-'a']; 29 } 30 if(p->id==0) 31 p->id = ++num; 32 return p->id; 33 } 34 35 int find(int x){ 36 if(x!=f[x]) 37 f[x] = find(f[x]); 38 return f[x]; 39 } 40 41 void unin(int x, int y){ 42 int fx = find (x); 43 int fy = find(y); 44 if(fx==fy) 45 return ; 46 else{ 47 f[fy] = fx; 48 } 49 } 50 int main() 51 { 52 for(int i=1;i<maxn;i++)//注意此处。。。已经好几次。。i<=maxn了。。。。。runtime error。。。悲催啊。。 53 f[i] = i; 54 char s1[30],s2[30]; 55 int id1,id2; 56 root = new node; 57 num =0; 58 while(scanf("%s%s",s1,s2)==2){ 59 id1 = maketrie(s1); 60 id2 = maketrie(s2); 61 degree[id1]++;//记录其节点的度数 62 degree[id2]++; 63 unin(id1,id2); 64 } 65 int s = find(1); 66 int cnt =0; 67 for(int i=1;i<=num;i++){ 68 if(degree[i]%2==1) 69 cnt++; 70 if(cnt>2){ 71 printf("Impossible "); 72 return 0; 73 } 74 if(find(i)!=s){//仅只有一个祖先节点,要不然就不是连通图。。就更不是欧拉路了。。 75 printf("Impossible "); 76 return 0; 77 } 78 } 79 if(cnt==1){//cnt 有可能为1.。。所以特殊说明。。 80 printf("Impossible "); 81 } 82 else{ 83 printf("Possible "); 84 } 85 86 return 0; 87 }