POJ 2513 Colored Sticks 欧拉路的判断+字典树

来源:互联网 发布:投影仪 网络接口 编辑:程序博客网 时间:2024/05/16 12:45

题目链接:

poj2513



题意:

给定一捆木棍。每根木棍的每个端点涂有某种颜色。问:是否能将这些棍子首尾相连,排成
一条直线,且相邻两根棍子的连接处端点的颜色一样。
输入描述:
输入文件中包含若干行,每行为两个单词,用空格隔开,表示一根棍子两个端点的颜色。表
示颜色的单词由小写字母组成,长度不超过10 个字符。木棍的数目不超过250000。
输出描述:
如果木棍能按照题目的要求排成一条直线,输出"Possible",否则输出"Impossible"。



解题思路:

判断能否排成一条直线,可将木棍理解为一条无向边,然后保存所有颜色点的度数,判断该图是否连通且是否构成欧拉路

题目没有给出颜色种类的最大值,所以要确定每种颜色的标号需要一种特殊的hash方法:字典树。


代码:

#include<iostream>#include<cstdio>#include<cstring>#define M 530000using namespace std;struct node{    int Id;    node* next[26];    node()    {        Id=-1;        for(int i=0; i<26; i++)            next[i]=NULL;    }}*Root;int fa[M];int degree[M];int num;int U_find(int x){    return x==fa[x]?x:fa[x]=U_find(fa[x]);}int trie_find(char str[]){    node* p=Root;    int len=strlen(str);    for(int i=0; i<len; i++)    {        if(p->next[str[i]-'a']==NULL)            p->next[str[i]-'a']=new node();        p=p->next[str[i]-'a'];    }    if(p->Id==-1)        p->Id=num++;    return p->Id;}int main(){    Root=new node();    num=0;    for(int i=0; i<M; i++)    {        fa[i]=i;        degree[i]=0;    }    char str1[12],str2[12];    int Id1,Id2;    while(~scanf("%s%s",str1,str2))    {        Id1=trie_find(str1);        Id2=trie_find(str2);        fa[U_find(Id1)]=U_find(Id2);        degree[Id1]++;        degree[Id2]++;    }    int s=0,Ancestor=0;    for(int i=0; i<num; i++)    {        if(U_find(i)==i)            Ancestor++;        if(degree[i]%2==1)            s++;    }    if(num==0)              //没有数据也是"Possible"        cout<<"Possible"<<endl;    else if(Ancestor==1&&(s==0||s==2))        cout<<"Possible"<<endl;    else        cout<<"Impossible"<<endl;    return 0;}


0 0