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 ", 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 ", 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 ", 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 "); 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 "); 128 else printf("Impossible "); 129 return 0; 130 }