题目链接:
https://vjudge.net/problem/POJ-2513
题目大意:
给一些木棍,两端都有颜色,只有两根对应的端点颜色相同才能相接,问能不能把它们接成一根木棍
解题思路:
题意不难,典型的无向图判断是否存在欧拉通路或回路的问题。
1、欧拉通路或回路的判定条件是图联通,并且度数为奇数的点只有两个或者0个
2、颜色多,输入的字符串多,需要用字典树存储,给字符串标号用字典树标记
3、点数多,用并查集判断连通性。
第一次WA:没由开is_word标记,写成了前缀判断,此处应该是单词判断
第二次WA:判断连通的时候简单地用p[i] == i;满足该条件的数目等于1来判断连通性,但是此题输入的图可能很复杂,应该判断是否所有点的根节点是同一个点这样进行判断。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<string> 5 #include<map> 6 #include<set> 7 #include<cmath> 8 #include<algorithm> 9 #include<vector> 10 #include<sstream> 11 #define lowbot(i) (i&(-i)) 12 using namespace std; 13 14 const int maxn = 1e6 + 10; 15 int tree[maxn][26]; 16 //字典树tree[u][v]表示编号为u的节点的下一个字母为v连接的节点的编号 17 int idx(char c){ return c - 'a'; }//可以写成宏定义 18 int tot = 1;//根节点编号为1 19 bool is_word[maxn]; 20 int sum[maxn]; 21 int cnt = 0;//cnt 22 int Insert(char s[], int u)//u表示根节点 23 //插入字符串s 24 { 25 for(int i = 0; s[i]; i++) 26 { 27 int c = idx(s[i]); 28 if(!tree[u][c]) 29 tree[u][c] = ++tot; 30 u = tree[u][c]; 31 } 32 sum[u] = ++cnt; 33 is_word[u] = 1;//标记单词结尾 34 return sum[u]; 35 } 36 37 int ID(char s[], int u)//返回单词s的编号 38 { 39 for(int i = 0; s[i]; i++) 40 { 41 int c = idx(s[i]); 42 if(!tree[u][c])//还没有编号 43 return Insert(s, 1); 44 u = tree[u][c]; 45 } 46 if(!is_word[u])//是前缀但是并不是单词 47 { 48 return Insert(s, 1); 49 } 50 return sum[u]; 51 } 52 int p[maxn];//并查集 53 int d[maxn];//记录每个点度数之和 54 int Find(int x) 55 { 56 return x == p[x] ? x : p[x] = Find(p[x]); 57 } 58 int main() 59 { 60 for(int i = 0; i < maxn; i++) 61 { 62 p[i] = i; 63 } 64 char s1[15], s2[15]; 65 int u, v, x, y; 66 while(scanf("%s%s", s1, s2) != EOF) 67 { 68 u = ID(s1, 1); 69 v = ID(s2, 1); 70 //cout<<u<<" "<<v<<endl; 71 x = Find(u); 72 y = Find(v); 73 if(x != y)p[x] = y; 74 d[u]++; 75 d[v]++; 76 } 77 int flag = 1, flag1 = 0; 78 //flag判断连通性 79 //flag1记录奇点度数的点的数目 80 int t = Find(1); 81 if(d[1] & 1)flag1++; 82 for(int i = 2; i <= cnt; i++) 83 { 84 if(Find(i) != t){flag = 0;break;} 85 if(d[i] & 1)flag1++; 86 } 87 if(flag && (flag1 == 0 || flag1 == 2)) 88 printf("Possible "); 89 else printf("Impossible "); 90 return 0; 91 }