欧拉路径 之 poj 2513 Colored Sticks
/*
欧拉路径 之 poj 2513 Colored Sticks
欧拉路径: 若图G中存在这样一条路径,使得它恰通过G中每条边一次,则称该路径为欧拉路径。
无向图存在欧拉路径 充要条件:
1) 图是连通的;
2) 所有节点的度为偶数,或者有且只有两个度为奇数的节点。
题目要求:
align the sticks in a straight line such that the colors of the endpoints that touch are of the same color.
模型转换:
木棒看作边,木棒两端看作节点(相同的颜色即为同一个节点),这样便可构成无向图G。
align the sticks in a straight line 即:在无向图G中,通过每条边一次。
即:判定无向图G是否存在欧拉路径
实现:
字典树 + 并查集
*/
1 #include <crtdbg.h> 2 #include <iostream> 3 #include <fstream> 4 #include <sstream> 5 #include <cstdlib> 6 #include <cstdio> 7 #include <cstddef> 8 #include <iterator> 9 #include <algorithm> 10 #include <string> 11 #include <locale> 12 #include <cmath> 13 #include <vector> 14 #include <cstring> 15 #include <map> 16 #include <utility> 17 #include <queue> 18 #include <stack> 19 #include <set> 20 #include <functional> 21 using namespace std; 22 typedef pair<int, int> PII; 23 typedef long long int64; 24 const int INF = 0x3f3f3f3f; 25 const int modPrime = 3046721; 26 const double eps = 1e-9; 27 const int MaxN = 500010; 28 const int MaxM = 10010; 29 30 31 int degree[MaxN]; 32 int ftr[MaxN]; 33 int rnk[MaxN]; 34 35 //Union-Find Sets 36 void ufsIni() 37 { 38 for (int i = 0; i < MaxN; ++i) 39 { 40 ftr[i] = i; 41 rnk[i] = 0; 42 } 43 } 44 int ufsFind(int x) 45 { 46 if (x == ftr[x]) return x; 47 return ftr[x] = ufsFind(ftr[x]); 48 } 49 void ufsUnite(int x, int y) 50 { 51 x = ufsFind(x); 52 y = ufsFind(y); 53 if (x == y) return; 54 55 if (rnk[x] > rnk[y]) 56 { 57 ftr[y] = x; 58 } 59 else 60 { 61 ftr[x] = y; 62 if (rnk[x] == rnk[y]) 63 { 64 ++rnk[y]; 65 } 66 } 67 } 68 69 // Tree 70 struct Tree 71 { 72 Tree *next[26]; 73 bool flag; 74 int num; 75 Tree() 76 { 77 flag = false; 78 memset(next, NULL, sizeof(next)); 79 } 80 }; 81 82 Tree *Root = new Tree; 83 84 int insertNode(string str, int num) 85 { 86 Tree *p = Root; 87 for (int i = 0; i < str.size(); ++i) 88 { 89 int pos = str[i] - 'a'; 90 if (!(p->next[pos])) 91 { 92 p->next[pos] = new Tree; 93 } 94 p = p->next[pos]; 95 } 96 if (!(p->flag)) 97 { 98 p->flag = true; 99 p->num = num; 100 } 101 return p->num; 102 } 103 104 void destroyTree(Tree *root) 105 { 106 for (int i = 0; i < 26; ++i) 107 { 108 if (root->next[i]) 109 { 110 destroyTree(root->next[i]); 111 } 112 } 113 delete[] root; 114 } 115 116 117 int main() 118 { 119 #ifdef HOME 120 freopen("in", "r", stdin); 121 //freopen("out", "w", stdout); 122 #endif 123 124 char str1[11], str2[11]; 125 int num = 0; 126 fill(degree, degree + MaxN, 0); 127 ufsIni(); 128 while (~scanf("%s %s", str1, str2)) 129 { 130 int numTmp1 = insertNode(str1, num); 131 if (numTmp1 == num) 132 { 133 ++num; 134 } 135 int numTmp2 = insertNode(str2, num); 136 if (numTmp2 == num) 137 { 138 ++num; 139 } 140 141 ++degree[numTmp1]; 142 ++degree[numTmp2]; 143 ufsUnite(numTmp1, numTmp2); 144 } 145 destroyTree(Root); 146 for (int i = 1; i < num; ++i) 147 { 148 if (ftr[i] != ftr[0]) 149 { 150 printf("Impossible\n"); 151 return 0; 152 } 153 } 154 int oddCnt = 0; 155 for (int i = 0; i < num; ++i) 156 { 157 if (degree[i] & 1) 158 { 159 ++oddCnt; 160 if (oddCnt >= 3) 161 { 162 break; 163 } 164 } 165 } 166 if (oddCnt == 0 || oddCnt == 2) 167 { 168 printf("Possible\n"); 169 } 170 else 171 { 172 printf("Impossible\n"); 173 } 174 175 176 #ifdef HOME 177 cerr << "Time elapsed: " << clock() / CLOCKS_PER_SEC << " ms" << endl; 178 _CrtDumpMemoryLeaks(); 179 #endif 180 return 0; 181 }