POJ 2513 Colored Sticks

解决一个有趣的问题:如何排列带有颜色端点的木棍,使相邻木棍的颜色匹配。使用字典树和并查集算法处理大量数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Colored Sticks
Time Limit: 5000MS Memory Limit: 128000K
Total Submissions: 35039 Accepted: 9155

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 oflowercase(小写字母) 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.


一个判断有无欧拉路的问题,数据比较大,用到了字典树和并查集。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<new>

using namespace std;

char a[15],b[15];

typedef struct node
{
    bool ff;
    int num;
    struct node * next[28];
}tree;

int cha[551234];
int hs[551234];
int cl=1;

int add(char ch[], tree * root)
{
    int len=strlen(ch);
    tree * you=root;
    for(int i=0;i<len;i++)
    {
        int tt=ch[i]-'a';
        if(you->next[tt]==NULL)
        {
            you->next[tt]=new tree;
            you->next[tt]->ff=false;
            for(int i=0;i<=26;i++) you->next[tt]->next[i]=NULL;
        }
        you=you->next[tt];
    }
    if(!you->ff)
    {
        you->ff=true;
        you->num=cl++;
    }
    return you->num;
}

int f(int x)
{
    if(!cha[x]) return x;
    return cha[x]=f(cha[x]);
}

void he(int c1,int c2)
{
    if(c1>c2)
    {
        int t=c1;
        c1=c2;
        c2=t;
    }
    c1=f(c1);
    c2=f(c2);
    if(c1!=c2) cha[c2]=c1;
}
char A[110];
int main()
{
    memset(hs,0,sizeof(hs));
    memset(cha,0,sizeof(cha));
    tree * root=new tree;
    root->ff=false;
    for(int i=0;i<=26;i++) root->next[i]=NULL;
    while(gets(A)&&A[0]!='\0')
    {
        sscanf(A,"%s%s",&a,&b);
        int c1,c2;
         c1=add(a,root); c2=add(b,root);
        hs[c1]++;
        hs[c2]++;
       he(c1,c2);
    }
 //   cout<<"1111";
    int dan=0,shu=0;
    for(int i=1;i<cl;i++)
    {
        if(hs[i]%2) dan++;
        if(!cha[i]) shu++;
        if(shu>1||dan>2) break;
    }
 //   cout<<dan<<" "<<shu<<endl;
    if((shu==0&&(dan==0||dan==2))||(shu==1&&(dan==0||dan==2)))
    cout<<"Possible"<<endl;
    else cout<<"Impossible"<<endl;
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值