Colored Sticks
Time Limit: 5000MS | Memory Limit: 128000K | |
Total Submissions: 36048 | Accepted: 9431 |
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.
用字典树保存字符串到id的映射。用并查集判断图是否连通。然后根据判断欧拉通路的定理:
图中无奇度顶点或恰好有两个奇度顶点。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <stack>
#include <bitset>
#include <queue>
#include <set>
#include <map>
#include <string>
#include <algorithm>
#define FOP freopen("data.txt","r",stdin)
#define inf 0x3f3f3f3f
#define maxn 500010
#define mod 1000000007
#define PI acos(-1.0)
#define LL long long
using namespace std;
struct Node
{
Node *br[26];
int num;
};
Node *head;
int cot = 0;
int degree[maxn];
int pre[maxn];
void initTrie()
{
head = new Node;
for(int i = 0; i < 26; i++) head->br[i] = NULL;
head->num = cot++;
}
int insertTrie(char *str)
{
Node *t, *s = head;
int len = strlen(str);
for(int i = 0; i < len; i++)
{
int id = str[i] - 'a';
if(s->br[id] == NULL)
{
t = new Node;
for(int j = 0; j < 26; j++)
{
t->br[j] = NULL;
}
t->num = 0;
s->br[id] = t;
}
s = s->br[id];
if(i == len - 1) s->num = cot++;
}
return cot-1;
}
int findTrie(char *str)
{
Node *s = head;
int c;
int len = strlen(str);
for(int i = 0; i < len; i++)
{
int id = str[i] - 'a';
if(s->br[id] == NULL) return 0;
else s = s->br[id], c = s->num;
}
return c;
}
int findUF(int x)
{
int r = x;
while(pre[r] != r) r = pre[r];
int i = x, j;
while(i != r)
{
j = pre[i];
pre[i] = r;
i = j;
}
return r;
}
void joinUF(int x, int y)
{
int fx = findUF(x), fy = findUF(y);
if(fx != fy) pre[fx] = fy;
}
int main()
{
//FOP;
initTrie();
for(int i = 1; i < maxn; i++) pre[i] = i;
char str1[12], str2[12];
int id1, id2;
while(~scanf("%s %s", str1, str2))
{
id1 = findTrie(str1);
if(!id1) id1 = insertTrie(str1);
id2 = findTrie(str2);
if(!id2) id2 = insertTrie(str2);
joinUF(id1, id2);
degree[id1]++, degree[id2]++;
}
int flag = 0;
int fa = findUF(1);
for(int i = 1; i < cot; i++)
{
if(degree[i] & 1) flag++;
if(findUF(i) != fa) {flag = -1; break;}
}
if(flag == 0 || flag == 2) printf("Possible\n");
else printf("Impossible\n");
return 0;
}