欧拉路径 之 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 }

 

 
posted @ 2016-01-04 16:42  JmingS  阅读(160)  评论(0编辑  收藏  举报