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.
字典树+并查集+欧拉回路
#include<cstdio>
#include<string.h>
const int maxv=30;
int color=0;
int degree[500010]={0};
int f[500010];
#include<string.h>
const int maxv=30;
int color=0;
int degree[500010]={0};
int f[500010];
//*****************字典树部分**********//
//建立字典树节点
typedef struct Node{
struct Node* next[maxv];
int flag;
typedef struct Node{
struct Node* next[maxv];
int flag;
//初始化节点内容
Node()
{
for(int i=0;i<30;i++)
{
next[i]=NULL;
}
flag=0;
}
Node()
{
for(int i=0;i<30;i++)
{
next[i]=NULL;
}
flag=0;
}
}node;
node* newnode()
{
return new node;
}
int insert(node* root,char s[20])
{
node *p=root;
for(int i=0;i<strlen(s);i++)
{
if(p->next[s[i]-'a']==NULL)
{
p->next[s[i]-'a']=newnode();
}
p=p->next[s[i]-'a'];
}
if(p->flag==0)
{
color++;
p->flag=color;
return p->flag;
}
return p->flag;
}
}
if(p->flag==0)
{
color++;
p->flag=color;
return p->flag;
}
return p->flag;
}
//*************并查集部分**********************//
//每次找父节点都会进行路径压缩?因该是这样这个递归不太理解
int findfather(int x)
{
if(f[x]==-1)return x;
return f[x]=findfather(f[x]);
}
int findfather(int x)
{
if(f[x]==-1)return x;
return f[x]=findfather(f[x]);
}
void Union(int a,int b)
{
int fa=findfather(a);
int fb=findfather(b);
if(fa!=fb)
f[fa]=fb;
}
int main()
{
memset(f,-1,sizeof(f) );
int cons1=0,cons2=0;
node *root=new node;
char st1[20],st2[20];
int m=0;
while(scanf("%s%s",st1,st2)!=EOF)
{
int t1=insert(root,st1);
int t2=insert(root,st2);
{
int t1=insert(root,st1);
int t2=insert(root,st2);
//用以标记每种颜色出现的次数,以便用欧拉回路判断合法性
degree[t1]++;
degree[t2]++;
degree[t1]++;
degree[t2]++;
if(findfather(t1)!=findfather(t2))
{
Union(t1,t2);
}
{
Union(t1,t2);
}
}
for(int i=1;i<=color;i++)
{
if((degree[i]+1)%2==0)
{
cons1++;
}
if(f[i]==-1)cons2++;
if(cons1>2||cons2>1)
{
break;
}
}
if((cons2==1||cons2==0)&&(cons1==0||cons1==2))//合并后应是一个集合此时cons2=1cons1=2,存在0根木棍情况此时cons2=0 cons1=0;
printf("Possible\n");
else
printf("Impossible\n");
}
else
printf("Impossible\n");
}