poj 2513 Colored Sticks (字典树+欧拉回路判定)

发布时间:2014-10-22 12:09:44编辑:www.fx114.net 分享查询网我要评论
本篇文章主要介绍了"poj 2513 Colored Sticks (字典树+欧拉回路判定)",主要涉及到poj 2513 Colored Sticks (字典树+欧拉回路判定)方面的内容,对于poj 2513 Colored Sticks (字典树+欧拉回路判定)感兴趣的同学可以参考一下。

Colored Sticks Time Limit: 5000MS   Memory Limit: 128000K Total Submissions: 27792   Accepted: 7346 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 The UofA Local 2000.10.14 感想: 以为这题很水,开始写的两个代码果断TLE,后来才发现要用字典树的知识,然后又是WA,原来还要考虑输入为空的时候的情况要输出“Possible”,汗。。。!这数据,真蛋疼。还有要注意的是这题应该看做无向图。 代码: #include <iostream> #include <cstdio> #include <cstring> #include <string> #include <cstdlib> #include <map> #define maxn 500005 #define MAX 26 using namespace std; int n,m,ans,t,num; int sset[maxn],srank[maxn]; int in[maxn]; char s1[105],s2[105]; struct Trie //Trie结点声明 { int isStr; //标记该结点处是否构成单词 Trie *next[MAX]; //儿子分支 }; void insert(Trie *root,const char*s) //将单词s插入到字典树中 { if(root==NULL||*s=='\0') return; int i; Trie *p=root; while(*s!='\0') { if(p->next[*s-'a']==NULL) //如果不存在,则建立结点 { Trie *temp=(Trie *)malloc(sizeof(Trie)); for(i=0; i<MAX; i++) { temp->next[i]=NULL; } temp->isStr=0; p->next[*s-'a']=temp; p=p->next[*s-'a']; } else { p=p->next[*s-'a']; } s++; } p->isStr=++t; //单词结束的地方标记此处可以构成一个单词 } int search(Trie *root,const char*s) //查找某个单词是否已经存在 { Trie *p=root; while(p!=NULL&&*s!='\0') { p=p->next[*s-'a']; s++; } if(p!=NULL&&p->isStr!=0) return p->isStr; //在单词结束处的标记为true时,单词才存在 return 0; } void del(Trie *root) //释放整个字典树占的堆区空间 { int i; for(i=0; i<MAX; i++) { if(root->next[i]!=NULL) { del(root->next[i]); } } free(root); } void init() { int i; for(i=0; i<maxn; i++) { sset[i]=i; srank[i]=1; } num=0; } int sfind(int x) // 查找时优化了路径 { int r=x,nn; while(sset[r]!=r) r=sset[r]; while(x!=r) { nn=sset[x]; sset[x]=r; x=nn; } return r; } void smerge(int a,int b) // 合并时将深度小的集合合并到大的里面 { int x,y; x=sfind(a); y=sfind(b); if(x!=y) { if(srank[x]<srank[y]) sset[x]=y; else { sset[y]=x; if(srank[x]==srank[y]) srank[x]++; } num++; } } bool solve() { int i,j,u,h; u=0; if(num!=t-1) return false ; for(i=1;i<=t;i++) { if(in[i]&1) u++; } if(u==0||u==2) return true ; return false ; } int main() { int i,j,x,y; t=0; init(); Trie *root= (Trie *)malloc(sizeof(Trie)); for(i=0; i<MAX; i++) { root->next[i]=NULL; } root->isStr=0; memset(in,0,sizeof(in)); while(~scanf("%s%s",s1,s2)) { x=search(root,s1); if(!x) // 不存在就建立 { insert(root,s1); x=t; } y=search(root,s2); if(!y) { insert(root,s2); y=t; } in[x]++; in[y]++; smerge(x,y); } if(t==0) { printf("Possible\n"); return 0; } if(solve()) printf("Possible\n"); else printf("Impossible\n"); // del(root); return 0; }

下一篇:hdu - 3660 - Alice and Bob's Trip