(NYoj 230)彩色棒 --欧拉通路,字典树,并查集

来源:互联网 发布:有网络无法连接 编辑:程序博客网 时间:2024/05/22 02:13

题目: 彩色棒
时间限制:1000 ms | 内存限制:128000 KB
难度:5
描述
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?
输入
the frist line have a number k(0< k<=10),that is the number of case. each case contais a number m,then have m line, 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 13 characters. There is no more than 250000 sticks.
输出
If the sticks can be aligned in the desired way, output a single line saying Possible, otherwise output Impossible.
样例输入
1
5
blue red
red violet
cyan blue
blue magenta
magenta cyan
样例输出
Possible

分析:
这题是个典型的判断欧拉通路的问题。但是有几点要注意:
1:整个图要是连通的。我们用并查集解决
2:我们要将不同的颜色用不同的数字表示。由于棒的数量很大,不用map()我们用字典树解决。
3:满足欧拉通路的条件。记录顶点度数即可。

AC代码:

#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;const int maxn=500010;int p[maxn],d[maxn];int id;struct node{    node* next[26];    int num;    node()    {        for(int i=0;i<26;i++)            next[i]=NULL;        num=-1;    }};int Trie(node * root, char* s){    node* p=root;    while(s[0]!='\0')    {        if(p->next[s[0]-'a']==NULL)        {            node* t=new node();            p->next[s[0]-'a']=t;            p=t;        }        else p=p->next[s[0]-'a'];        s++;    }    if(p->num==-1)        p->num=id++;    return p->num;}void dfs(node* root){    if(root==NULL) return ;    for(int i=0;i<26;i++)    {        if(root->next[i]!=NULL)        {            dfs(root->next[i]);        }    }    free(root);}int find(int x){    return p[x]==-1?x:p[x]=find(p[x]);}void unit(int x,int y){    int xx=find(x);    int yy=find(y);    if(xx!=yy)        p[xx]=yy;}int main(){    int t,n;    scanf("%d",&t);    while(t--)    {        char s1[15],s2[15];        id=0;        node* r = new node();        memset(p,-1,sizeof(p));        memset(d,0,sizeof(d));        scanf("%d",&n);        getchar();        if(n==0)        {            printf("Possible\n");continue;        }        int a,b;        for(int i=0;i<n;i++)        {            scanf("%s %s",s1,s2);            a=Trie(r,s1);b=Trie(r,s2);            d[a]++;d[b]++;            unit(a,b);        }        dfs(r);        bool flag=true;        int k=find(0);        for(int i=0;i<id;i++)        {            if(k!=find(i))            {                flag=false;break;            }        }        if(!flag)        {            printf("Impossible\n");continue;        }        int num=0;        for(int i=0;i<id;i++)        {            if(d[i]%2==1)                num++;            if(num>2)                break;        }        if(num==0 || num==2)            printf("Possible\n");        else printf("Impossible\n");    }    return 0;}
0 0
原创粉丝点击