poj 2513 并查集,Trie(字典树), 欧拉路径

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

Hint

Huge input,scanf is recommended.
 
给你若干木棒和木棒两端的颜色,要你判断能否将这些木棒连成一条线,要求接触的两端颜色需要相同。
木棒个数不超过25万,那么颜色最多可以达到50万。这种类型的题是欧拉路径的经典题目, 需要判断是否为连接图,由于几十万的数据,一开始用的是bfs,超时。后来看了discuss用了并查集,跑了1.3s左右,是最快的三倍。然而可以过。。。。注意HINT,建议用scanf,说明用cin容易超时(事实上我也用string试过,果然超时。。),由于颜色使用字符串表示,而string和cin又太慢,这个时候就需要用到字典树了,关于字典树,欧拉路径, 并查集可以在网上查找资料。
上代码
  1 #include <cstring>
  2 #include <cstdio>
  3 #include <iostream>
  4 #define maxn 500000 + 10
  5 using namespace std;
  6 char str[maxn][12];
  7 int sum = 0;
  8 struct Node
  9 {
 10     int ID;
 11     Node *next[27];
 12     Node()
 13     {
 14         ID = -1;
 15         for(int i = 0; i < 27; i++)
 16         {
 17             next[i] = NULL;
 18         }
 19     }
 20 };
 21 Node *newnode(){return new Node;}
 22 Node *root = newnode();
 23 int getID(char *s)
 24 {
 25     Node *u = root;
 26     int len = strlen(s);
 27     for(int i = 0; i < len; i++)
 28     {
 29         int x = s[i] - 'a';
 30         if(u->next[x] == NULL)
 31             u->next[x] = newnode();
 32         u = u->next[x];
 33     }
 34     if(u->ID == -1)
 35     {
 36         return u->ID = sum++;
 37     }
 38     return u->ID;
 39 }
 40 ///并查集
 41 int fat[maxn];
 42 int R[maxn];
 43 int gettop(int a)
 44 {
 45     if(fat[a] != a)
 46     {
 47         fat[a] = gettop(fat[a]);
 48         //printf("top[%d] = %d\n", a, fat[a]);
 49     }
 50     else return a;
 51 }
 52 void Link(int a, int b)
 53 {
 54     int x = gettop(a);
 55     int y = gettop(b);
 56     if(a == b) return;
 57     if(R[a] < R[b])
 58     {
 59         fat[a] = fat[b];
 60     }
 61     else
 62     {
 63         fat[b] = fat[a];
 64         if(R[a] == R[b])
 65             R[a]++;
 66     }
 67 
 68 }
 69 int num[maxn];
 70 int main()
 71 {
 72     for(int i = 0; i < maxn; i++)
 73     {
 74         fat[i] = i;
 75         memset(str[i], 0, sizeof(str[i]));
 76     }
 77     memset(R, 0, sizeof(R));
 78     memset(num, 0, sizeof(num));
 79     char s[12], t[12];
 80 
 81     while(scanf("%s%s", &s, &t) != EOF)
 82     {
 83         int a = getID(s);
 84         int b = getID(t);
 85         int l1 = strlen(s);
 86         int l2 = strlen(t);
 87         if(str[a][0] != 0)
 88         {
 89             for(int i = 0; i < l1; i++)
 90                 str[a][i] = s[i];
 91             str[a][l1] = 0;
 92         }
 93         if(str[b][0] != 0)
 94         {
 95             for(int i = 0; i < l2; i++)
 96                 str[b][i] = t[i];
 97             str[b][l2] = 0;
 98         }
 99         num[a]++;
100         num[b]++;
101         Link(a, b);
102         //printf("fat[%d]=%d, fat[%d]=%d\n", a, fat[a], b, fat[b]);
103     }
104     int ok = 1;
105     int Top = fat[0];
106     for(int i = 0; i < sum; i++)
107     {
108        // printf("top[%d] = %d\n", i, gettop(i));
109         gettop(i);
110         if(fat[i] != Top)
111         {
112 
113             ok = 0;
114             break;
115         }
116     }
117     if(ok)
118     {
119        // printf("Wrong is here\n");
120         int NUM = 0;
121         for(int i = 0; i < sum; i++)
122         {
123             if(num[i] % 2) NUM++;
124         }
125         if(NUM > 2) ok = 0;
126     }
127     if(ok) printf("Possible\n");
128     else printf("Impossible\n");
129     return 0;
130 }

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

posted on 2017-04-24 21:33  子狼  阅读(191)  评论(0编辑  收藏  举报

导航