题目链接:http://poj.org/problem?id=2513
题目大意:

一些木棒,两端都涂上颜色,求是否能将木棒首尾相接,连成一条直线,要求不同木棒相接的一端必须是相同颜色的。

思路:

现在就是把颜色字符串抽象成点,用字典树进行染色就行了,当然如果图不连通的话,显然不成立,用并查集维护无向图的连通块就可以了,然后就是判断点的度数就行了。

#include <bits/stdc++.h>
using namespace std;

int cut;
int d[500010];
/***********并查集***********/

int a[500010];
int fd(int x)
{
    if(a[x]<0)
    {
        return x;
    }
    return a[x]=fd(a[x]);
}

int L(int x, int y)
{
    x=fd(x), y=fd(y);
    if(x!=y)
    {
        a[x]=y;
    }
}


/***************************/

/**********字典树***********/
struct Tree{
    bool vis;//标记
    int id;  //编号
    Tree *next[26];
    Tree()
    {
        vis=0;
        id=0;
        memset(next, 0, sizeof(next));
    }
};

int Insert(Tree *root, char *s)
{
    Tree *p=root;
    int i=0;
    while(s[i])
    {
        if(p->next[s[i]-'a']==NULL)//如果该位置 找不到 s[i], 就开一个,指向它
        {
            Tree *t=new Tree();
            p->next[s[i]-'a']=t;
        }
        p=p->next[s[i]-'a'];//继续跑
        i++;
    }
    if(p->vis)//如果之前有过了,直接返回编号
    {
        return p->id;
    }
    else//之前没有,就先标记,然后赋值,返回值。
    {
        p->vis=true;
        p->id=cut++;//标记
        return p->id;
    }
}

void del(Tree *root)//删除字典树(多样例)
{
    for(int i=0;i<26;i++)
    {
        if(root->next[i]!=NULL)
        {
            del(root->next[i]);
        }
    }
    free(root);
}
/**********************/

/*******初始化*******/

void inio()
{
    memset(a, -1, sizeof(a));
    memset(d, 0, sizeof(d));
    cut=1;
}

/********************/

int main()
{
    //freopen("1.txt", "r", stdin);//文件读入
    inio();
    Tree *root=new Tree();
    char a[20], b[20];
    while(scanf("%s%s",a, b)!=EOF)
    {
        int x=Insert(root, a);
        int y=Insert(root, b);
        d[x]++, d[y]++;
        L(x, y);
    }
    int ans=0, flog=0;
    int T=fd(1);
    for(int i=1;i<cut;i++)
    {
        if(fd(i)!=T)
        {
            flog=1;
            break;
        }
        if(d[i]%2==1)
        {
            ans++;
        }
    }
    if(ans>2||flog)
    {
        printf("Impossible\n");
    }
    else
    {
        printf("Possible\n");
    }
    del(root);

    return 0;
}