Colored Sticks
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 Hint Huge input,scanf is recommended.
Source |
这个题目涉及了多个基本数据结构和算法
虽然简单,但是很有代表性。
知识考查点:1,字典树;2,欧拉路:其中又考察了判断是否为连通图;3,并查集;
题意不难理解,可是我们得巧妙的转化一下,我们把棍子头的颜色当作节点,棍子就当作线 于是就形成了下面的图
那么问题就可以转化为将这个图一笔画,要求每根线段都要走到而且只能走一次,于是这就转化为了欧拉路的判断,即亮点,一,图是联通的. 二,该图每个点的度数要么全为偶数,要么有且仅有两个点的度数为奇数。
先岔开,我们建立字典树就是判断存储有多少种颜色,和每种颜色的个数分别是多少。
回到上面,图是否联通,可以在首先处理的时候把连同的点都归结到一个点上,如上面我全部归结到BLUE上,这个就是根,最后判断如果所有的点都归结在一个相同点上即联通;于是我们只要判断第二个条件,这里我们就利用二叉树保存下来的结果,判断为颜色数目为基数的个数是不是少于或者等于2,是就是POSSIBLE,不是就IMPOSSIBLE。
#include <iostream> #include <cstdio> #include <cstring> #include <cstdlib> using namespace std; typedef struct node { bool isLeaf; int key; struct node* next[26]; }Node; const int NODE_NUM=500000; int color[NODE_NUM+1]; int parent[NODE_NUM+1]; int color_cnt=1; Node* root; void createSet(int x) { parent[x]=x; } int find(int x) { if(parent[x]!=x) parent[x]=find(parent[x]); return parent[x]; } void unionSet(int a, int b) { int pa,pb; pa=find(a); pb=find(b); parent[pb]=pa; } int search(char word[15]) { Node *p, *temp; int len; int index; p=root; len=0; while(word[len]) { index=word[len]-'a'; if(!p->next[index]) { temp=(Node*)malloc(sizeof(Node)); temp->isLeaf=false; temp->key=-1; memset(temp->next,0,sizeof(temp->next)); p->next[index]=temp; } p=p->next[index]; len++; } if(p->isLeaf) return p->key; p->isLeaf=true; p->key=color_cnt; color_cnt++; return p->key; } int main() { char str1[15], str2[15]; int a,b; int m; int pa; root=(Node*)malloc(sizeof(Node)); root->isLeaf=false; root->key=0; memset(root->next,0,sizeof(root->next)); memset(color,0,sizeof(color)); for(int i=1; i<=NODE_NUM; i++) { createSet(i); } m=0; while(scanf("%s%s",str1, str2)!=EOF) { a=search(str1); b=search(str2); color[a]++; color[b]++; unionSet(a,b); } for(int i=1; i<color_cnt; i++) { if(color[i]%2!=0) m++; } pa=find(1); for(int i=2; i<color_cnt;i++) { if(pa!=find(i)) { m=-1; break; } } if(m == 2 || m == 0) printf("Possible\n"); else printf("Impossible\n"); return 0; }