POJ 2513 Colored Sticks 欧拉路+字典树

本文介绍了一种利用无向图与字典树解决木棒配对问题的方法。首先构建无向图来表示木棒的连接关系,然后通过字典树映射颜色编号,最后判断是否存在欧拉路或欧拉回路来确定木棒是否能首尾相连形成直线。文章详细解释了每一步的操作及其背后的原理。
摘要由CSDN通过智能技术生成

点击打开链接

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

思路
注意
1 此题需要构建无向图;
2 通过字典树得到每种颜色所对应的编号
3 通过判断是否为欧拉路或欧拉回路
    无向图欧拉回路  : 图联通 ,并且所有的点的度都为偶数
    无向图欧拉路  : 图联通 ,并且只有两个点的度都为为奇数
    联通的判断 利用并查集


字典树用于映射编号;
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#define LL long long
using namespace std;

struct node
{
    int id;
    int next[26];
}p[2500000];  //
int top;  ///前向星
int ID;  ///标号
int Creat()
{
    memset(p[top].next,-1,sizeof(p[top].next));
    p[top].id=0;
    return top++;
}
int Build(char s[])
{
    int k=0;
    int len=strlen(s);
    for(int i=0;i<len;i++)
    {
        int ch=s[i]-'a';
        if(p[k].next[ch]==-1)
            p[k].next[ch]=Creat();
        k=p[k].next[ch];
    }
    if(!p[k].id)
    {
        p[k].id=ID;       ///映射出 字母对应的编号
        ID++;
        return p[k].id;
    }
    else
        return p[k].id;
}
int bin[2600000];
int Find(int x)
{
    return x==bin[x]?x:bin[x]=Find(bin[x]);
}
int Union(int x,int y)
{
    int fx=Find(x);
    int fy=Find(y);
    if(fx!=fy)
        bin[fx]=fy;
}
int du[2500001];
int main()
{
    char s1[20],s2[20];
    top=0;
    ID=1;
    for(int i=0;i<2500001;i++)
        bin[i]=i;
    int k=Creat();
    while(~scanf("%s%s",s1,s2))
    {
      //  if(s1[0]=='0')
      //      break;
        int x=Build(s1);
        int y=Build(s2);
        du[x]++;
        du[y]++;
        Union(x,y);
    }
    int root=Find(1);
    int flag=0;
    if(ID==1)
    {
        printf("Possible\n");
        return 0;
    }
    for(int i=1;i<ID;i++)
    {
        if(Find(i)!=root)  ///不连通
        {
                flag=3;
                break;
        }
        if(du[i]%2)
            flag++;
    }
    if(flag==0||flag==2)
        printf("Possible\n");
    else 
        printf("Impossible\n");
    return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值