首页 > 代码库 > poj 2513 Colored Sticks 彩色棒
poj 2513 Colored Sticks 彩色棒
poj 2513 Colored Sticks
http://poj.org/problem?id=2513
题意:现在有几个木棒,每个木棒端点都着色,问:能否将它们排成一排,同时要满足相邻的的两端点颜色是一样的。
trie+并查集+欧拉通路
方法:要想排成一排,可以变向的理解为从一个图里找到一个欧拉通路(一定要想到);如果只是孤零零的一个个小棒,这道题很难实现。
首先:要先要对所有颜色进行编号,由于事先又不知道有几种颜色,有哪几种颜色。故有一个笨方法,用map<int,string>容器存出现过的颜色,每次在对一个颜色进行编号时要遍历map里的每一个颜色,没有的话添后面,有的话返回颜色所对应的编号。题目中提到颜色最多有500000中颜色,每次查找时最坏的情况是查找次数为500000,会超时。因此这里就要用到trie树,虽然每次也要寻找该颜色是否出现过,但是每次查找最坏情况只是该单词的长度(10),ok?
其次:该题木就可以简化顶点标有序号的一个图,要从中判断有否 欧拉通路:1.图是联通的(用并查集判断)2.图中顶点的度要么没有奇数,要么有2个奇数度顶点。
难点:能想到转化为图,找欧拉通路
trie树的另一个作用:编序号!!!!!
1 #include <stdio.h> 2 #include <string.h> 3 #include <iostream> 4 #include <algorithm> 5 #include <cstdio> 6 #include <cstring> 7 #include <cmath> 8 #include <stack> 9 #include <queue> 10 #include <functional> 11 #include <vector> 12 #include <map> 13 using namespace std; 14 #define M 0x0f0f0f0f 15 #define min(a,b) (a>b?b:a) 16 #define max(a,b) (a>b?a:b) 17 int cnt=1;//单词的个数 18 int father[500002]; 19 int v[500002]; 20 struct tree 21 { 22 struct tree *next[30]; 23 int ji;//标记该结点处是否构成单词,还代表该单词的编号 24 }; 25 int insert_(struct tree *root,char *s)//通过trie树对每一种颜色进行编号 26 { 27 int i; 28 if(*s==‘\0‘||root==NULL) 29 return 0; 30 struct tree *p=root; 31 while(*s!=‘\0‘) 32 { 33 if(p->next[*s-‘a‘]==NULL) 34 { 35 struct tree *t=(struct tree *)malloc(sizeof(struct tree)); 36 for(i=0; i<30; i++) 37 { 38 t->next[i]=NULL; 39 } 40 t->ji=0; 41 p->next[*s-‘a‘]=t; 42 p=t; 43 } 44 else 45 p=p->next[*s-‘a‘]; 46 s++; 47 } 48 if(p->ji==0) 49 p->ji=cnt++; 50 return p->ji; 51 } 52 53 //并查集,判断是否联通 54 void inte() 55 { 56 for(int i=0; i<500003; i++) 57 father[i]=i; 58 } 59 60 int find_(int a) 61 { 62 if(father[a]==a) 63 return a; 64 return find_(father[a]); 65 } 66 67 void unin(int a,int b) 68 { 69 int a1=find_(a); 70 int b1=find_(b); 71 if(a1!=b1) 72 father[a1]=b1; 73 } 74 75 int main() 76 { 77 int a1,b1; 78 char a[13],b[13]; 79 int i; 80 struct tree *root=(struct tree *)malloc(sizeof(struct tree)); 81 for(i=0; i<30; i++) 82 root->next[i]=NULL; 83 root->ji=0; 84 memset(v,0,sizeof(v)); 85 inte(); 86 while(scanf("%s %s",a,b)!=EOF) 87 { 88 a1=insert_(root,a); 89 b1=insert_(root,b); 90 v[a1]++; 91 v[b1]++; 92 unin(a1,b1); 93 } 94 int mm=find_(1); 95 int flag=0; 96 int flag1=0; 97 if(v[1]%2) 98 flag1++; 99 for(i=2; i<cnt; i++)100 {101 if(mm!=find_(i))102 flag=1;103 if(v[i]%2)104 {105 flag1++;106 }107 }108 109 if(flag)//bu lian tong110 printf("Impossible\n");111 else if(flag1==0||flag1==2)//ke yibi hua112 printf("Possible\n");113 else114 printf("Impossible\n");115 return 0;116 }
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。