POJ -2513 Colored Sticks 字典树 + 并查集 + 欧拉路

Colored Sticks
Time Limit: 5000MS   Memory Limit: 128000K
Total Submissions: 24844   Accepted: 6542

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
  1 #include<stdio.h>
  2 #include<string.h>
  3 #include<stdlib.h>
  4 typedef struct node
  5 {
  6     int order;         //存储该颜色在对应数组中的编号
  7     struct node *next[26];
  8 }node;
  9 
 10 //注意最多有250000个棒,所以最多应该有500000种颜色
 11 int father[500005];   //并查集中记录父亲节点
 12 int degree[500005];   //记录每个颜色出现的次数,用于欧拉路的判断
 13 
 14 int t,k;     //t为记录标号增加的数组指针,k为静态内存分配时的数组指针
 15 
 16 int search(char *s,node *T)         //返回s所表示的颜色在数组中的编号
 17 {
 18     int len,i,j,id,flag=0;
 19     node *p,*q;
 20     len=strlen(s);
 21     p=T;
 22     for(i=0;i<len;++i)
 23     {
 24         id=s[i]-'a';
 25         if(p->next[id]==NULL)
 26         {
 27             flag=1;
 28             q=(node *)malloc(sizeof(node));
 29             for(j=0;j<26;++j)
 30                 q->next[j]=NULL;
 31             p->next[id]=q;
 32         }
 33         p=p->next[id];
 34     }
 35     if(flag)    //肯定是新出现的颜色---因为有新开辟的节点
 36     {
 37         p->order=t;         //t存储该颜色在数组中对应的编号
 38         degree[t++]++;      //该颜色的度增加一
 39         return p->order;
 40     }
 41     else
 42     {
 43         if(p->order==0)   //也是新颜色----因为没有颜色在此标记
 44         {
 45             p->order=t;         //t存储该颜色在数组中对应的编号
 46             degree[t++]++;      //该颜色的度增加一
 47             return p->order;
 48         }
 49         degree[p->order]++;      //出现过的颜色,对应的度增加一
 50         return p->order;
 51     }
 52 }
 53 
 54 int find_father(int i)
 55 {
 56     if(father[i]==-1)
 57         return i;
 58     else
 59         return find_father(father[i]);
 60 }
 61 
 62 void merge(int num1,int num2)
 63 {
 64     num1=find_father(num1);
 65     num2=find_father(num2);
 66     if(num1!=num2)
 67     {
 68         if(father[num1]<father[num2])     //father[num1]的绝对值大
 69             father[num2]=num1;
 70         else
 71             father[num1]=num2;
 72     }
 73 }
 74 
 75 int main()
 76 {
 77     int i,num1,num2,flag;
 78     char s1[20],s2[20];
 79     node *T;
 80     t=1;      //从1号开始算起
 81     flag=0;
 82     memset(father,-1,sizeof(father));
 83     memset(degree,0,sizeof(degree));
 84     T=(node *)malloc(sizeof(node));
 85     T->order=0;
 86     for(i=0;i<26;++i)
 87         T->next[i]=NULL;
 88     while(scanf("%s%s",s1,s2)!=EOF)
 89     {
 90         num1=search(s1,T);
 91         num2=search(s2,T);
 92         merge(num1,num2);
 93     }
 94     for(i=1;i<t;++i)        //共有t-1种颜色
 95         if(father[i]==-1)
 96             ++flag;
 97     if(flag>1)                //说明不连通
 98         printf("Impossible\n");
 99     else
100     {
101         flag=0;
102         for(i=1;i<t;++i)
103             if(degree[i]&1)            //统计奇数度结点出现的次数
104                 ++flag;
105         if(flag==2||flag==0)        //无向图G具有一条欧拉路,当且仅当G是连通的,且有零个或两个奇数度结点
106             printf("Possible\n");
107         else
108             printf("Impossible\n");
109     }
110     return 0;
111 }

 

你可能感兴趣的:(color)