1. 程式人生 > >POJ 2513 Colored Sticks(Tire+歐拉回(通)路判斷)

POJ 2513 Colored Sticks(Tire+歐拉回(通)路判斷)

cstring ios ins 色相 logs 代碼 pan root degree

題目鏈接:http://poj.org/problem?id=2513

題目大意:你有好多根棍子,這些棍子的兩端分都別塗了一種顏色。請問你手中的這些棍子能否互相拼接,從而形成一條直線呢?

兩根棍子只有在顏色相同的時候才能拼接。比如有兩根棍子,第一根棍子的兩端的顏色分別為blue green,第二根兩端的顏色為blue red,那麽他們就可以拼接成green blue blue red或者red blue blue green。 解題思路:跟之前寫的POJ1386很像,都是首尾連通。但是這裏需要用字典樹(不能用map會超時)對這些顏色單詞做處理分配編號,然後這些顏色就是一個個節點了,就可以建圖了,然後判斷一下是不是歐拉回(通)路即可。註意,這裏的木棍可以反轉,所以是無向圖,還有輸入的字符串數目可能為0要特判一下輸出“Possible”。 代碼:
 1
#include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #define CLR(arr,val) memset(arr,val,sizeof(arr)) 6 using namespace std; 7 const int M=5e5+5; 8 9 struct Tire{ 10 Tire *next[26]; 11 int flag; 12 Tire(){ 13 for
(int i=0;i<26;i++) 14 next[i]=NULL; 15 flag=-1; 16 } 17 }; 18 int degree[M],fa[M],color; 19 20 int Insert(char *str,Tire *&root){//要插入的字符串str 21 Tire *p=root; 22 for(int i=0;str[i]!=\0;i++){ 23 int k=str[i]-a; 24 if(p->next[k]==NULL)
25 p->next[k]=new Tire; 26 p=p->next[k]; 27 } 28 if(p->flag==-1) 29 p->flag=++color; 30 return p->flag; 31 } 32 33 void del(Tire *root){ //動態建樹後要釋放內存 34 for(int i=0;i<26;i++) 35 if(root->next[i]) 36 del(root->next[i]); 37 delete(root); 38 } 39 40 int find(int x){ 41 return fa[x]==x?x:fa[x]=find(fa[x]); 42 } 43 44 int main(){ 45 char str1[20],str2[20]; 46 Tire *root=new Tire; 47 for(int i=1;i<M;i++){ 48 fa[i]=i; 49 } 50 while(~scanf("%s%s",str1,str2)){ 51 int u,v; 52 u=Insert(str1,root); 53 v=Insert(str2,root); 54 degree[u]++; 55 degree[v]++; 56 if(find(u)!=find(v)) 57 fa[find(u)]=find(v); 58 } 59 del(root); 60 bool flag=true; 61 int cnt1=0,cnt2=0,chu,ru; 62 for(int i=1;i<=color;i++){ 63 if(find(i)==i) 64 cnt1++; 65 if(degree[i]%2==1) 66 cnt2++; 67 } 68 //註意有字符串為0的情況,還有這是無向圖 69 if((cnt1==1||cnt1==0)&&(cnt2==0||cnt2==2)) 70 puts("Possible"); 71 else 72 puts("Impossible"); 73 return 0; 74 }

POJ 2513 Colored Sticks(Tire+歐拉回(通)路判斷)