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
题意:木棒两段有不同的颜色,两木棒相同颜色的一端可以连接。输入每个木棒两端的颜色,问是否可以将所有木棒连接成一条线。
思路:木棒数量即颜色数量太多,普通数组不方便存储,所以采用字典树。而颜色的两两关联性又与并查集相似,用并查集将各颜色关联。注意题意是将木棒连成一条线,所以题目要求构建欧拉图或欧拉回路,即一笔画的图,欧拉图或欧拉回路要求度为奇数的点小于两个,其他个点度为偶数。
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cstdlib>
using namespace std;
struct node
{
int next[27];
int num;
}d[510015];
int degree[510015],arr[510015];
int top,no;
int creat(char a[])
{
int x,i;
int len=strlen(a);
int j=0;
for (i=0;i<len;i++)
{
x=a[i]-'a';
if(d[j].next[x]==0)
{
d[j].next[x]=++top;
}
j=d[j].next[x];
}
if(d[j].num==0)
{
d[j].num=++no;
}
return d[j].num;
}
int Find(int r)
{
return r==arr[r] ? r : arr[r]=Find(arr[r]);
}
void Union(int x,int y)
{
int fx=Find(x);
int fy=Find(y);
if(fx!=fy)
{
arr[fx]=fy;
}
}
int main()
{
memset(d,0,sizeof(d));
memset(degree,0,sizeof(degree));
int i;
for (i=1;i<=510015;i++)
arr[i]=i;
char str1[15],str2[15];
top=0;no=0;
while (scanf("%s%s",str1,str2)!=EOF)
{
int x=creat(str1);
int y=creat(str2);
degree[x]++;
degree[y]++;
Union(x,y);
}
int sum=0;
int flag=0;
for (i=1;i<=no;i++) //判断奇数度个数
{
if(degree[i]&1)
sum++;
if(sum>2)
{
printf("Impossible\n");
return 0;
}
}
for (i=1;i<=no;i++) //判断根节点个数
{
if(arr[i]==i)
flag++;
if(flag>1)
{
printf("Impossible\n");
return 0;
}
}
printf("Possible\n");
return 0;
}