Colored Sticks
| Time Limit: 5000MS |
|
Memory Limit: 128000K |
| Total Submissions: 16750 |
|
Accepted: 4248 |
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 Input
blue redred violetcyan blueblue magentamagenta cyan
Sample Output
Possible
Hint
Huge input,scanf is recommended./*<br />題目大意:每個木棒頭尾都有兩種顏色,木棒末端顏色相同的可以串連成一條直線,問能否將所有木棒串連起來組成一條直線。<br />題目求解:傳換成圖的問題就是求解能否一筆畫成(歐拉通路)<br />代碼技巧:用數組字典樹和鏈表字典樹都可以,我看很多用鏈表的,那我就來一個靜態吧。<br />ps:沒注意檢查那個下標,真的鬱悶死我了。調試半天</p><p>Source Code</p><p>Problem: 2513 User: wawadimu<br />Memory: 64224K Time: 938MS<br />Language: C++ Result: Accepted </p><p>Source Code<br />*/<br />#include<iostream><br />using namespace std;</p><p>#define maxn 50001<br />int father[maxn];//i的父親數組<br />int rank[maxn];//i所在集合的秩(樹的高度)<br />int degree[maxn];//節點的度數</p><p>struct node//字典樹<br />{<br /> int key;<br /> int next[26];<br /> node()<br /> {<br /> key=0;//這裡0和-1都可以只要是沒有用過的就可以.<br /> memset(next,-1,sizeof(next));<br /> }<br />}trie[600000];//其實不用這麼多,但是也沒超記憶體<br />unsigned int loc=2;//記錄當前新節點<br />unsigned int num=1;//單詞數目<br />int insert(char *str)//字典樹的插入操作<br />{<br /> int index,r=1;<br /> int len=strlen(str);<br /> for(int i=0;i<len;i++)<br /> {<br /> index=str[i]-'a';//最初這個用'A',沒有注意到顏色使用小寫字母的,本地運算由於資料居然沒有報錯,調試很半天才發現.暈<br /> if(trie[r].next[index]==-1)<br /> {</p><p> trie[r].next[index]=loc++;//尾插法,nex[index]記錄index的下一個節點座標<br />r=loc-1;<br /> }<br /> else<br /> {<br /> r=trie[r].next[index];<br /> }<br /> }<br /> if(trie[r].key==0)//字典樹單詞不存在<br /> {<br /> trie[r].key=num++;<br /> }<br /> return trie[r].key;<br />}<br />void _make_set(int x)//開始每一個i都是一個獨立的集合<br />{<br /> father[x]=x;<br /> degree[x]=0;<br /> rank[x]=0;<br />}<br />int _find_set(int x)//尋找x的所在集合,並遞迴壓縮路徑<br />{<br /> if(x!=father[x])<br /> {<br /> father[x]=_find_set(father[x]);<br /> }<br /> return father[x];<br />}<br />void _union(int x,int y)//合并兩個集合,<br />{<br /> if(x==y) return;<br /> if(rank[x]>rank[y])//將秩少的合并到秩多的根結點,避免退化成線性<br /> {<br /> father[y]=x;<br /> }<br /> else<br /> {<br /> if(rank[y]==rank[x])<br /> rank[y]++;<br /> father[x]=y;<br /> }<br />}<br />int main()<br />{<br /> //freopen("2513.txt","r",stdin);<br /> int i,j;<br /> char s1[11], s2[11];<br /> for (i = 0; i < maxn; i++)<br /> {<br /> _make_set(i);<br /> }<br /> while(scanf("%s%s",s1,s2)!=EOF)<br /> {<br /> //cout<<s1<<" "<<s2<<endl;<br /> int x=insert(s1);<br /> int y=insert(s2);<br /> degree[x]++;<br /> degree[y]++;<br /> //cout<<x<<" "<<y<<endl;<br /> _union(_find_set(x),_find_set(y));<br />//cout<<father[x]<<endl;<br /> }<br /> int sum=0;<br />num--;<br />//cout<<num<<endl;<br /> for(i=1;i<=num;i++)<br /> if(degree[i]%2) sum++;//<br />// cout<<sum<<endl;<br />//存在歐拉通路的條件:奇頂點數為0或者2,並且圖是連通圖.<br /> if(sum>2) printf("Impossible/n");//奇頂點<br /> else<br /> {<br /> for(j=2;j<=num;j++)//檢查是否為連通圖<br /> {<br /> if(_find_set(j)!=_find_set(1))<br /> {<br /> printf("Impossible/n");<br /> return 1;<br /> }<br /> }<br /> printf("Possible/n");<br /> }<br /> return 1;<br />}</p><p>