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 }

 

posted @ 2017-04-07 21:51  Robin!  阅读(138)  评论(0编辑  收藏  举报