Colored Sticks
Time Limit: 5000MS | Memory Limit: 128000K | |
Total Submissions: 27267 | Accepted: 7212 |
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.
题意:给出n条线段,线段的两个端点都有颜色。线段两两相连当且仅当相连的端点颜色相同,问能否将所有线段连成一条。
思路:判断是否存在欧拉路径。
无向图存在欧拉路的充要条件为:
① 图是连通的;(用并查集判断)
② 所有节点的度为偶数,或者有且只有两个度为奇数的节点
另外,需要将所有字符串插入到字典树中,这样能快速找到字符串对应的下标。
AC代码:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <cstdio>
using namespace std;
const int maxn=250005*2;
typedef struct TireNode
{
int id;
struct TireNode *next[26];
}TireNode;
TireNode Memory[1000000];
int allocp=0;
TireNode *root;
int fa[maxn],degree[maxn];
TireNode *CreateTireNode()
{
TireNode *p;
p=&Memory[allocp++];
p->id=0;
for(int i=0;i<26;i++)
p->next[i]=NULL;
return p;
}
void InsertTire(char *str,int ii)
{
int i=0,k;
TireNode *p=root;
while(str[i])
{
k=str[i++]-'a';
if(p->next[k]==NULL)
p->next[k]=CreateTireNode();
p=p->next[k];
}
p->id=ii;
}
int SearchTire(char *s)
{
int i=0,k;
TireNode *p=root;
while(s[i])
{
k=s[i++]-'a';
if(p->next[k]==NULL) return 0;
p=p->next[k];
}
return p->id;
}
void init()
{
root=CreateTireNode();
for(int i=1;i<maxn;i++)
fa[i]=i;
memset(degree,0,sizeof(degree));
}
int Find_set(int x)
{
if(x==fa[x]) return x;
fa[x]=Find_set(fa[x]);
return fa[x];
}
int main()
{
char s1[15],s2[15];
int cnt=1;
init();
while(scanf("%s %s",s1,s2)!=EOF)
{
int a=SearchTire(s1);
if(!a)
{
InsertTire(s1,cnt);
a=cnt++;
}
degree[a]++;
int b=SearchTire(s2);
if(!b)
{
InsertTire(s2,cnt);
b=cnt++;
}
degree[b]++;
int ra=Find_set(a);
int rb=Find_set(b);
if(ra!=rb) fa[rb]=ra;
}
if(cnt==0)
printf("Possible\n");
else
{
int c=0;
for(int i=1;i<cnt;i++)
if(i==fa[i]) c++;
if(c>1)
printf("Impossible\n");
else
{
c=0;
for(int i=1;i<cnt;i++)
if(degree[i]&1) c++;
if(c>2)
printf("Impossible\n");
else
printf("Possible\n");
}
}
return 0;
}