周赛-Colored Sticks 分类: 比赛 2015-08-02 09:33 7人阅读 评论(0) 收藏

Colored Sticks
Time Limit: 5000MS Memory Limit: 128000K
Total Submissions: 32423 Accepted: 8556
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
字典树+并查集+欧拉路径

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <list>
#include <algorithm>
#define LL long long
#define RR freopen("output.txt","r",stdoin)
#define WW freopen("input.txt","w",stdout)

using namespace std;

const int MAX = 2500000;

struct node
{
    int num;
    node *next[26];
}head;

int pre[MAX];

int Du[MAX];

int top;

char s[15],c[15];

node *Creat()
{
    node *p;
    p=new node;
    p->num=0;
    for(int i=0;i<26;i++)
    {
        p->next[i] =  NULL;
    }
    return p;
}

int Build_Tree(char *str)//建立字典树
{
    int len=strlen(str);
    int a;
    node *p=&head;
    for(int i=0;i<len;i++)
    {
        a=str[i]-'a';
        if(p->next[a])
        {
            p=p->next[a];
        }
        else
        {
            p->next[a]=Creat();
            p=p->next[a];
        }
    }
    if(!p->num)//返回单词所在的位置
    {
        p->num=++top;
    }
    return p->num;
}
int Find(int x)//并查集+压缩路径
{
    int i=x,j=x,s;
    while(pre[i]!=-1)
    {
        i=pre[i];
    }
    while(pre[j]!=-1)
    {
        s=pre[j];
        pre[j]=i;
        j=s;
    }
    return i;
}
void Link(int x,int y)
{
    int FX=Find(x);
    int FY=Find(y);
    if(FX!=FY)
    {
        pre[FX]=FY;
    }
}
int main()
{
    memset(pre,-1,sizeof(pre));
    memset(Du,0,sizeof(Du));
    top=0;
    for(int i=0;i<26;i++)
    {
        head.next[i]=NULL;
    }
   // int n;
   // scanf("%d",&n);
    //for(int i=0;i<n;i++)
    while(~scanf("%s %s",s,c))
    {
       // scanf("%s %s",s,c);
        int u=Build_Tree(s);
        int v=Build_Tree(c);
        Du[u]++;
        Du[v]++;
        Link(u,v);
    }
    int ans=0,ant=0;
    for(int i=1;i<=top;i++)
    {
        if(Du[i]%2)
        {
            ans++;
        }
        if(pre[i]==-1)
        {
            ant++;
        }
        if(ant>1||ans>2)//如果入度为奇数的超过2个,或者根大于一个就不能连成一条直线
        {
            break;
        }
    }
    if(ant>1||ans>2)
    {
        printf("Impossible\n");
    }
    else
    {
        printf("Possible\n");
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

posted @ 2015-08-02 09:33  一骑绝尘去  阅读(139)  评论(0编辑  收藏  举报