POJ-2513 Colored Sticks 【欧拉通路+Trie】
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
题解:
把每种颜色看成顶点,棍子看成边,即转化为求是否存在欧拉通路问题,这题数据量大,Map超时,用hash恰当的mod值取不来(discuss里神tm1000过了一脸懵逼),用Trie可以过。
代码:
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cstring> 5 #include<queue> 6 #include<map> 7 using namespace std; 8 const int N = 250000 * 2 + 5; 9 int deg[N], p[N]; 10 struct Edge { 11 int u, v; 12 }edge[N]; 13 14 int ch[N][26], val[N], num = 0, tot = 0; 15 int insert(char *s) { 16 int now = 0, len = strlen(s); 17 for (int i = 0; i < len; ++i) { 18 int id = s[i] - 'a'; 19 if (!ch[now][id]) ch[now][id] = ++num; 20 now = ch[now][id]; 21 } 22 val[now] = ++tot; 23 return val[now]; 24 } 25 26 int find(char *s) { 27 int now = 0, len = strlen(s); 28 for (int i = 0; i < len; ++i) { 29 int id = s[i] - 'a'; 30 if (!ch[now][id]) return 0; 31 now = ch[now][id]; 32 } 33 return val[now]; 34 } 35 36 int Find(int x) {return x == p[x] ? x : p[x] = Find(p[x]);} 37 38 void Union(int x, int y) { 39 x = Find(x); y = Find(y); 40 if (x != y) p[x] = y; 41 } 42 43 bool bconnect(int n, int m) { 44 for (int i = 1; i <= m; ++i) p[i] = i; 45 for (int i = 0; i < n; ++i) { 46 int u = edge[i].u, v = edge[i].v; 47 if (u != v) Union(u, v); 48 } 49 for (int i = 2; i <= m; ++i) 50 if (Find(i) != Find(1)) return false; 51 return true; 52 } 53 54 int main() { 55 char s1[15], s2[15]; 56 int edgenum = 0, u, v; 57 while (~scanf("%s%s", s1, s2)) { 58 u = find(s1); v = find(s2); 59 if (!u) u = insert(s1); 60 if (!v) v = insert(s2); 61 edge[edgenum].u = u; 62 edge[edgenum].v = v; 63 ++edgenum; 64 deg[u]++; deg[v]++; 65 } 66 bool eular = true; 67 int odd = 0; 68 for (int i = 1; i <= tot; ++i) { 69 if (deg[i] % 2 == 1) ++odd; 70 if (odd > 2) {eular = false; break;} 71 } 72 if (!bconnect(edgenum, tot)) eular = false; 73 if (eular) printf("Possible\n"); 74 else printf("Impossible\n"); 75 76 return 0; 77 }