poj 2513 Colored Sticks (trie树+并查集+欧拉路)

Colored Sticks
Time Limit: 5000MS   Memory Limit: 128000K
Total Submissions: 40043   Accepted: 10406

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.
 
题目大意:
给定n根木棒,首尾各有一种颜色。求问有没有可能,将这些木棒连成一排,使得接头处颜色相同。
 
判断无向图是否存在欧拉路经典题。
一根木棒其实就是给两种颜色连上一条无向边(可能会有重边的)。那么一条欧拉路就相当于一种连接方式。
无向图存在欧拉图的条件:
1)联通。这个交给并查集就好了。
2)度数为奇数的点只能是0个或2个。这个建图的时候或建完图后都挺好处理的。
主要是如何建图呢。字符串太多了,要hash成数。用字典树比较合适。
每次遇见一种颜色,看字典树中有没有该颜色。如果有,返回该颜色的id,否则加入该颜色,id取全局变量++col。
 
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<stack>
#include<deque>
typedef long long ll;
const int maxn=250000;

int col;
struct ttrie
{
    bool isword;
    int id;
    ttrie* next[26];
    ttrie()
    {
        isword=false;
        for(int i=0;i<26;i++)
            next[i]=NULL;
    }
};

char str1[15],str2[15];

int add(ttrie* root,char str[])
{
    ttrie *p=root,*q;
    for(int i=0;str[i]!='';i++)
    {
        int temp=str[i]-'a';
        if(p->next[temp]==NULL)
        {
            q=new ttrie;
            p->next[temp]=q;
            p=q;
        }
        else
            p=p->next[temp];
    }
    if(p->isword)
        return p->id;
    else
    {
        p->isword=true;
        p->id=++col;
        return p->id;
    }
}

int degree[maxn*2+5];
int cnt;
struct tedge
{
    int u,v;
};
tedge edge[maxn+5];

int fa[maxn*2+5];

int getfa(int x)
{
    if(fa[x]==x)
        return x;
    else
        return fa[x]=getfa(fa[x]);
}

int main()
{
    col=0;
    ttrie* root=new ttrie;

    memset(degree,0,sizeof(degree));
    cnt=0;
    while(scanf("%s%s",str1,str2)!=EOF)
    {
        int u=add(root,str1);
        int v=add(root,str2);
        degree[u]++;
        degree[v]++;
        edge[++cnt]=(tedge){u,v};
    }

    bool flag=true;
    for(int i=1;i<=col;i++)
        fa[i]=i;
    int tot=col;
    for(int i=1;i<=cnt;i++)
    {
        int fx=getfa(edge[i].u);
        int fy=getfa(edge[i].v);
        if(fx!=fy)
        {
            fa[fx]=fy;
            tot--;
        }
    }
    if(tot>1)
        flag=false;
    if(flag)
    {
        int odd=0;
        for(int i=1;i<=col;i++)
        {
            if(degree[i]%2)
                odd++;
        }
        if(odd!=0&&odd!=2)
            flag=false;
    }
    if(flag)
        printf("Possible
");
    else
        printf("Impossible
");

    return 0;
}
View Code
原文地址:https://www.cnblogs.com/acboyty/p/9979760.html