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

来源:互联网 发布:淘宝男模特赚钱吗 编辑:程序博客网 时间:2024/05/22 02:31

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;}
0 0
原创粉丝点击