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
Hint
Huge input,scanf is recommended.
Source
有一端颜色相同的可以接到一块,那么就默认颜色相同的拼到一起了,然后每行给出两个颜色,对两个颜色进行合并,看看最后是否是一个连通图,如果是连通图了,还得拍成一行,也就是一笔走完所有点,就是判断欧拉图,奇数度的点最多两个,注意有坑,如果一行数据也没有,也是Possible。
这里用字典树,记录每种颜色,返回对应的下标,然后进行并查集合并,以此判断是否为连通图。记录每种颜色出现次数,判断他的度数的奇偶性。
代码:
#include <iostream> #include <cstdio> #include <sstream> #include <cstring> #define MAX 2000005 using namespace std; int pos,pos1; int trie[MAX][26],num[MAX],to[MAX]; int f[MAX]; int odd,root; int Insert(char *s) { int i = 0,c = 0; while(s[i]) { int d = s[i] - 'a'; if(!trie[c][d]) trie[c][d] = ++ pos; c = trie[c][d]; i ++; } if(!to[c]) { to[c] = ++ pos1; f[pos1] = pos1; } num[to[c]] ++; return to[c]; } int getf(int x) { return f[x] == x ? f[x] : f[x] = getf(f[x]); } void Union(int x,int y) { int xx = getf(x); int yy = getf(y); if(xx != yy) { f[xx] = yy; } } int main() { char s[20],t[20]; while(~scanf("%s%s",s,t)) { int d = Insert(s); int e = Insert(t); Union(d,e); } for(int i = 1;i <= pos1;i ++) { if(getf(i) == i) root ++; if(num[i] % 2) odd ++; } if(root <= 1 && odd <= 2)puts("Possible"); else puts("Impossible"); }