POJ2513 -Colored Sticks(The UofA Local 2000.10.14)

来源:互联网 发布:vb replace函数用法 编辑:程序博客网 时间:2024/06/06 08:37

Problem : Colored Sticks
Description :

给你一些木棒,木棒两端有颜色,现在问你把所有木棒首位连接起来是否可能,注意,只有端点的颜色相同时才能连接。

Solution :

欧拉通路判定+字典树HASH。我们把颜色看成图中的点,木棒看成边。那么这个题就转化成了“图中边是否能全部走一遍并且不能重复走”,这就是经典的欧拉通路问题。判断欧拉通路只需要判定图是否连通与奇数度的个数。图的连通性我们可以用并查集快速搞定,关键就是这些颜色如何映射成序号的点。我一开始想用map来搞一下,当时看Disscuss说map不行,于是知道了字典树来HASH以此代替map。学习了学习了。

Code(C++) :

#include <stdio.h>#include <string.h>#include <iostream>using namespace std;struct Node{    int id;    Node *next[26];    Node(){        id=-1;        for(int i=0;i<26;i++)            next[i]=NULL;    }}Root;int ID=0;const int MAXN=250000*2+50;int p[MAXN],de[MAXN];int make(char str[]){    Node *p=&Root;    for(int i=0;str[i];i++){        int pos=str[i]-'a';        if(p->next[pos]==NULL){            p->next[pos]=new Node();        }        p=p->next[pos];    }    if(p->id==-1)        p->id=++ID;    return p->id;}int find(int x){    return x==p[x]? x:p[x]=find(p[x]);}int main(){    //freopen("in","r",stdin);    for(int i=0;i<MAXN;i++)        p[i]=i,de[i]=0;    char color1[15],color2[15];    while(~scanf("%s%s",color1,color2)){        int id1=make(color1);        int id2=make(color2);        //printf("id1:%d id2:%d\n",id1,id2);        de[id1]++,de[id2]++;        int tx=find(id1);        int ty=find(id2);        if(tx!=ty)            p[tx]=ty;    }    int odd=0;    int root=find(1);    bool f=true;    for(int i=1;i<=ID;i++){        odd+=de[i]%2;        if(root!=find(i)){            f=false;            break;        }    }    if(!(odd==0||odd==2)){            f=false;    }    puts(f? "Possible":"Impossible");    return 0;}
0 0