导航

POJ 2513 【字典树】【欧拉回路】

Posted on 2015-10-07 19:26  tun~  阅读(161)  评论(0编辑  收藏  举报

题意:

有很多棒子,两端有颜色,告诉你两端的颜色,让你把这些棒子拼接起来要求相邻的接点的两个颜色是一样的。

问能否拼接成功。

思路:

将颜色看作节点,将棒子看作边,寻找欧拉通路。

保证图的连通性的时候用到并查集。

这里颜色由于是字符串代替,所以需要用到字典树优化离散化过程。

字典树的学习感谢博客http://www.ahathinking.com/archives/14.html

重点是这个图很棒:

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<map>
#include<string>
#include<iostream>
#include<stdlib.h>
using namespace std;
int me[250000*2+55];
int out[500005];
struct ti
{
    void add(char *,int);
    int findi(char *);
    ti *mine[26];
    int num;
};
void ti::add(char *s,int tmp)
{
    int len=strlen(s);
    ti *next=this;
    for(int i=0;i<len;i++)
    {
        if(next->mine[s[i]-96]==NULL)
        {
            next->mine[s[i]-96]=(ti*)malloc(sizeof(ti));
            memset(next->mine[s[i]-96]->mine,NULL,sizeof(mine));
            next->mine[s[i]-96]->num=0;
        }
        next=next->mine[s[i]-96];
    }
    next->num=tmp;
}
int ti::findi(char *s)
{
    int len=strlen(s);
    ti *next=this;
    for(int i=0;i<len;i++)
    {
        if(next->mine[s[i]-96]==NULL)
        {
            return 0;
        }
        next=next->mine[s[i]-96];
    }
    return next->num;
}
ti tree;
int findme(int n)
{
    if(n!=me[n])
        return me[n]=findme(me[n]);
    return n;
}
int main()
{
    memset(tree.mine,NULL,sizeof(tree.mine));
    tree.num=0;
    char col1[15],col2[15];
    for(int i=1;i<=500050;i++)
    {
        me[i]=i;
    }
    int num=0;
    while(scanf("%s%s",col1,col2)!=EOF)
    {
        if(tree.findi(col1)==0)
        {
            num++;
            tree.add(col1,num);
        }
        if(tree.findi(col2)==0)
        {
            num++;
            tree.add(col2,num);
        }
        int tmpa=findme(tree.findi(col1));
        int tmpb=findme(tree.findi(col2));
        if(tmpa!=tmpb)
            me[tmpb]=tmpa;
        out[tree.findi(col1)]++;
        out[tree.findi(col2)]++;
    }
    int c=0;
    int x,y,z;
    x=y=z=0;
    for(int i=1;i<=num;i++)
    {
        if(me[i]==i)
            c++;
        if(out[i]&1)
            x++;
    }
    if(x==1||c>1||x>2)
        printf("Impossible\n");
    else
        printf("Possible\n");
}