Colored Sticks
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成立的条件:
1.奇度数结点个数为0或2。
2.图连通。
impossible成立的条件(以下两点中的一个):
1.奇度数结点个数为1或大于2。
2.图不连通。
示例程序
Source Code
Problem: 2513 Code Length: 1449B
Memory: 73544K Time: 1344MS
Language: GCC Result: Accepted
#include <stdio.h>
#include <stdlib.h>
struct trie
{
int d;
struct trie *n[26];
};
int a[500000],id=0;
struct trie *create()
{
int i;
struct trie *p;
p=(struct trie *)malloc(sizeof(struct trie));
for(i=0;26>i;i++)
{
p->n[i]=NULL;
}
p->d=-1;
return p;
};
int insert(struct trie *t,char s[])
{
int i;
for(i=0;s[i]!='\0';i++)
{
if(t->n[s[i]-'a']==NULL)
{
t->n[s[i]-'a']=create();
}
t=t->n[s[i]-'a'];
}
if(t->d==-1) //为每个颜色进行编号,用于并查集判断和度的记录
{
t->d=id;
id++;
}
return t->d;
}
int find(int x)
{
while(x!=a[x])
{
x=a[x];
}
return x;
}
int main()
{
int deg[500000],x,y,t,num,bug,i; //deg[500000]每个点度的数量
char s[11],s1[11];
struct trie *h=create();
for(i=0;500000>i;i++)
{
a[i]=i;
deg[i]=0;
}
while(scanf("%s %s",s,s1)!=EOF) //数据的记录,输入结束是EOF
{
x=insert(h,s);
deg[x]++;
y=insert(h,s1);
deg[y]++;
x=find(x);
y=find(y);
a[y]=x;
}
t=find(0); //记录第一个头
num=0;
bug=0;
for(i=0;id>i;i++)
{
if(deg[i]%2==1)
{
num++;
}
if(num>=3) //度为奇数的个数大于2时不满足条件
{
bug=1;
break;
}
if(find(i)!=t) //有多个头不满足条件
{
bug=1;
break;
}
}
if(bug==1||num==1) //不满足条件或者图中度为奇数的个数只有一个,输出不可能
{
printf("Impossible");
}
else
{
printf("Possible");
}
return 0;
}