POJ 2513 Colored Sticks (欧拉回路 + 字典树 +并查集)

Colored Sticks
Time Limit: 5000MS   Memory Limit: 128000K
Total Submissions: 27097   Accepted: 7175

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.

Source

 

详细解释:http://blog.csdn.net/lyy289065406/article/details/6647445

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>

using namespace std;

struct Trie{
    int x;
    Trie *next[26];
}*root,memory[5100000];

int deg[5100000],father[510000],cnt,tot;

Trie *create(){
    Trie *p=&memory[cnt++];
    for(int i=0;i<26;i++)
        p->next[i]=NULL;
    return p;
}

void InsertTrie(char *str,int x){
    Trie *loc=root;
    for(int i=0;str[i]!='\0';i++){
        int id=str[i]-'a';
        if(loc->next[id]==NULL)
            loc->next[id]=create();
        loc=loc->next[id];
    }
    loc->x=x;
}

int SearchTrie(char *str){
    Trie *loc=root;
    for(int i=0;str[i]!='\0';i++){
        int id=str[i]-'a';
        if(loc->next[id]==NULL)
            return 0;
        loc=loc->next[id];
    }
    return loc->x;
}

void init(){
    for(int i=1;i<=501000;i++)
        father[i]=i;
    memset(deg,0,sizeof(deg));
    cnt=0;
    tot=0;
}

int findSet(int x){
    if(x!=father[x]){
        father[x]=findSet(father[x]);
    }
    return father[x];
}

int judge(){        //判断是否满足欧拉 
    int odd=0;
    for(int i=1;i<=tot;i++)
        if(deg[i]%2==1)
            odd++;
    if(odd!=0 && odd!=2)
        return 0;
    int k=findSet(1);
    for(int i=2;i<=tot;i++)
        if(k!=findSet(i))
            return 0;
    return 1;
}

int main(){

    //freopen("input.txt","r",stdin);

    char s1[15],s2[15];
    init();
    root=create();
    while(~scanf("%s%s",s1,s2)){
        int x=SearchTrie(s1);   //映射求编号速度太慢
        int y=SearchTrie(s2);   //用字典树来求编号
        if(x==0)
            InsertTrie(s1,x=++tot);
        if(y==0)
            InsertTrie(s2,y=++tot);
        deg[x]++;
        deg[y]++;
        int fx=findSet(x);
        int fy=findSet(y);
        if(fx!=fy)
            father[fx]=fy;
    }
    if(judge())
        printf("Possible\n");
    else
        printf("Impossible\n");
    return 0;
}

 

posted @ 2013-07-03 23:51  Jack Ge  阅读(460)  评论(0编辑  收藏  举报