您的位置:首页 > 其它

文章标题 POJ 2523 : Colored Sticks(字典树+并查集+欧拉路径)

2016-11-13 21:01 483 查看

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.

题意: 有一些木棒,木棒的两头各带有一种颜色,现在问能否将这些木棒连起来,使得连起来的木棒的颜色是吻合的。

分析:很容易看出来这是一个判断是否是一个欧拉路径的问题,将每种颜色看成一个点,一个木棒看成一条边。而判断是否是一个欧拉路径需满足是一个连通图,并且每个点的度都为偶数或者只有两个点是奇数。判断连通性可以用并查集。

代码:

#include<iostream>
#include<string>
#include<cstdio>
#include<cstring>
#include<vector>
#include<math.h>
#include<map>
#include<queue>
#include<algorithm>
using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn=5000005;
int fa[maxn];//并查集
int color;//颜色的种数
int find(int x){
return fa[x]==x? x:fa[x]=find (fa[x]);
}
void merger(int x,int y){
int f1=find(x),f2=find(y);
if (f1!=f2){
fa[f1]=f2;
}
}
struct node {
node *nex[26];
int x;
};
node *root;
node* create(){//创建节点并将其nex赋为NULL
node * p = new node ;
for (int i=0;i<26;i++){
p->nex[i]=NULL;
}
return p;
}

void insert(char* word,int x){
node *p=root;
int k;
for (int i=0;word[i];i++){
k=word[i]-'a';
if (p->nex[k]==NULL){//如果没有该节点就创建节点
p->nex[k]=create();
}
p=p->nex[k];
}
p->x=x;//记录该节点是第x个单词的最后一个字母
}
int search(char* word){//查找单词
node *p=root;
int k;
for (int i=0;word[i];i++){
k=word[i]-'a';
if (p->nex[k]==NULL)return 0;
p=p->nex[k];
}
return p->x;
}
int sum[500005];
char a[15],b[15];
int judge(){//判断能否形成欧拉路径
int cnt=0;
for (int i=1;i<=color;i++){//判断是否是连通图
if (fa[i]==i) cnt++;
}
if (cnt>1)return 0;
int odd=0;
for (int i=1;i<=color;i++){
if (sum[i]%2)odd++;
}
if (odd==0||odd==2) return 1;//能形成欧拉路经
return 0;
}
int main ()
{

for (int i=1;i<=maxn;i++)fa[i]=i;
memset (sum,0,sizeof (sum));
color=0;
root=create();
while(scanf ("%s%s",a,b)!=EOF){
int x=search(a);
int y=search(b);
if (x==0) insert(a,x=++color);//如果没有该单词就插入
if (y==0) insert(b,y=++color);
sum[x]++;
sum[y]++;
merger(x,y);
}
int flag=judge();
if (flag) printf ("Possible\n");
else printf ("Impossible\n");
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  poj