POJ 2513 Colored Sticks(Tire+欧拉回(通)路判断)
Posted Yeader
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了POJ 2513 Colored Sticks(Tire+欧拉回(通)路判断)相关的知识,希望对你有一定的参考价值。
题目链接: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+欧拉回(通)路判断)的主要内容,如果未能解决你的问题,请参考以下文章
POJ-2513 Colored Sticks 欧拉通路+Trie