Colored Sticks(欧拉回路+字典树+并查集)

来源:互联网 发布:阿里云快还是腾讯云快 编辑:程序博客网 时间:2024/06/04 01:01
Colored Sticks
Time Limit: 5000MS Memory Limit: 128000KTotal Submissions: 36365 Accepted: 9519

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 redred violetcyan blueblue magentamagenta cyan

Sample Output

Possible

Hint

Huge input,scanf is recommended.

Source


题意:现在有几个木棒,每个木棒端点都着色,问:能否将它们排成一排,同时要满足相邻的的两端点颜色是一样的一笔画问题)。

trie+并查集+欧拉通路

该题就可以简化顶点标有序号的一个图,要从中判断有否  欧拉通路:1.图是联通的(用并查集判断)2.图中顶点的度要么没有奇数,要么有2个奇数度顶点。

注:linux下结束EOF用CTRL+D,windows用CTRL+Z

#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>using namespace std;int pre[500010],in[500010];int cnt=1;struct node{   int id;   struct node*next[30];};struct node*creat(){    struct node*p;    p=(struct node*)malloc(sizeof(struct node));    p->id=0;    for(int i=0;i<30;i++)    {        p->next[i]=0;    }    return p;}int insert(struct node*r,char s[]){    struct node*p=r;    if(r==NULL||s[0]=='\0')    return 0;    int len=strlen(s);    for(int i=0;i<len;i++)    {        int t=s[i]-'a';//字典树就是在该子母位置处开辟新空间,下一个字母也是这样操作        if(p->next[t]==NULL)        {           p->next[t]=creat();           p=p->next[t];        }        else p=p->next[t];//指针后移    }    if(p->id==0)    p->id=cnt++;    return p->id;//返回序号,全部操作完}int find(int r){   while(r!=pre[r])   {      r=pre[r];   }   return r;}void judge(int x,int y){   int fx=find(x),fy=find(y);   if(fx!=fy)   {      pre[fx]=fy;   }}int main(){    char a[20],b[20];    int a1,b1;    struct node*r;    r=creat();//开辟新节点    for(int i=0;i<=500010;i++)    {       pre[i]=i;    }    memset(in,0,sizeof(in));    while(scanf("%s%s",a,b)!=EOF)    {       a1=insert(r,a);       b1=insert(r,b);//返回序号       judge(a1,b1);//通过并查集联通       in[a1]++;       in[b1]++;    }    int flag=0,flag1=0;    int m=find(1);    if(in[1]%2)    flag1++;    for(int i=2;i<cnt;i++)    {        if(find(i)!=m)//不是一条线就不对        flag=1;        if(in[i]%2)        flag1++;    }    if(flag)    printf("Impossible\n");    else if(flag1==0||flag1==2)//度为0或2    printf("Possible\n");    else    printf("Impossible\n");    return 0;}


0 0
原创粉丝点击