http://poj.org/problem?id=2513
题意:
给定一些木棒,木棒两端都涂上颜色,求是否能将木棒首尾相接,连成一条直线,要求不同木棒相接的一边必须是相同颜色的。
思路:
题目很明显的是欧拉道路的问题。
欧拉道路的关键是:
①图是连通的。
②最多只能有两个奇点。(不能只存在一个奇点)
本来是想用map映射的,但是太多了,比较费时,这里用字典树的话会比较省时,判断图是否连通可以用并查集来完成。
1 #include<iostream> 2 #include<algorithm> 3 #include<string> 4 #include<cstring> 5 using namespace std; 6 7 const int maxn = 500000 + 5; 8 int p[maxn], deg[maxn]; 9 int cnt; 10 11 struct Trie 12 { 13 int ch[maxn][30]; 14 int vis[maxn]; 15 int sz; 16 17 void init() 18 { 19 sz = 1; 20 memset(ch[0], 0, sizeof(ch[0])); 21 } 22 23 int insert(char *s, int& v) 24 { 25 int u = 0, n = strlen(s); 26 for (int i = 0; i < n; i++) 27 { 28 int c = s[i]-'a'; 29 if (!ch[u][c]) 30 { 31 memset(ch[sz], 0, sizeof(ch[sz])); 32 vis[sz] = 0; 33 ch[u][c] = sz++; 34 } 35 u = ch[u][c]; 36 } 37 if (!vis[u]) vis[u] = ++v; 38 return vis[u]; 39 } 40 }t; 41 42 int find(int x) 43 { 44 return x == p[x] ? x : find(p[x]); 45 } 46 47 void merge(int x, int y) 48 { 49 int fx = find(x); 50 int fy = find(y); 51 if (fx != fy) 52 p[fx] = fy; 53 } 54 55 int main() 56 { 57 //freopen("D:\txt.txt", "r", stdin); 58 char a[20], b[20]; 59 t.init(); 60 memset(deg, 0, sizeof(deg)); 61 for (int i = 0; i <= maxn; i++) p[i] = i; 62 cnt = 0; 63 while (~scanf("%s %s", a, b)) 64 { 65 int id1 = t.insert(a,cnt); 66 int id2 = t.insert(b,cnt); 67 deg[id1]++; 68 deg[id2]++; 69 merge(id1, id2); 70 } 71 int ans = 0; 72 for (int i = 1; i <= cnt; i++) 73 { 74 if (deg[i] % 2 == 1) ans++; 75 if (ans > 2 || find(1) != find(i)) 76 { 77 printf("Impossible "); 78 return 0; 79 } 80 } 81 if (ans == 1) 82 printf("Impossible "); 83 else 84 printf("Possible "); 85 return 0; 86 }