Colored Sticks
Time Limit: 5000MS |
| Memory Limit: 128000K |
Total Submissions: 34615 |
| Accepted: 9047 |
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
题目大意:给你一堆小木棍 ,木棍两端是有颜色的,如果某一个木棍的尾部和某一个木棍的首部颜色相同,辣么这两个可以连接起来,问能否将给出的所有小木棍连接起来
思路:
欧拉路判断:图中奇数度的点只可能是0个或者两个。
连通判断:并查集。
字母转换成编号:字典树、POJ这个题卡了hash卡了map、正解是用字典树来解决,操作很简单》如果这个单词在树里边有编号,那么使用这个编号作为节点号,否则对应下一个节点号入树即可。
注意:初始化和空白数据,空白数据应该输出Possible
Ac代码:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<map>
using namespace std;
#define maxn 26
typedef struct tree
{
int flag;
tree *next[maxn];
} tree;
tree root;
int f[510000];
int degree[510000];
int find(int a)
{
int r=a;
while(f[r]!=r)
r=f[r];
int i=a;
int j;
while(i!=r)
{
j=f[i];
f[i]=r;
i=j;
}
return r;
}
void merge(int a,int b)
{
int A,B;
A=find(a);
B=find(b);
if(A!=B)
f[B]=A;
}
void creat(char *str,int val)
{
int len=strlen(str);
tree *p=&root,*q;
for(int i=0; i<len; i++)
{
int id=str[i]-'a';
if(p->next[id]==NULL)
{
q=(tree *)malloc(sizeof(root));
for(int j=0; j<26; j++)
{
q->next[j]=NULL;
}
p->next[id]=q;
}
p=p->next[id];
if(i==len-1)p->flag=val;
}
}
int find(char *str)
{
int len=strlen(str);
tree *p=&root;
for(int i=0; i<len; i++)
{
int id=str[i]-'a';
p=p->next[id];
if(p==NULL)
return 0;
}
return p->flag;
}
int main()
{
for(int i=0; i<26; i++)
{
root.next[i]=NULL;
root.flag=0;
}
char a[100];
char b[100];
for(int i=1; i<=510000; i++)f[i]=i,degree[i]=0;
int cont=1;
while(~scanf("%s%s",a,b))
{
//if(strcmp(a,"end")==0)break;
int u=find(a);
int v=find(b);
if(u==0)
{
creat(a,cont);
u=cont;
cont++;
}
if(v==0)
{
creat(b,cont);
v=cont;
cont++;
}
degree[u]++;
degree[v]++;
merge(u,v);
}
if(cont==1)
{
printf("Possible\n");
}
else
{
int tot=0;
for(int i=1; i<cont; i++)
{
if(f[i]==i)tot++;
}
if(tot==1)
{
int output=0;
for(int i=1; i<cont; i++)
{
if(degree[i]%2==1)output++;
}
if(output==0||output==2)
{
printf("Possible\n");
}
else printf("Impossible\n");
}
else printf("Impossible\n");
}
}