Colored Sticks
Time Limit: 5000MS | Memory Limit: 128000K | |
Total Submissions: 20750 | Accepted: 5482 |
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
要仔细看题,木棍不仅仅只是可以一个方向放置,还可以倒过来,所以简单的说,这个题是一个无向图的欧拉回路判断
但是直接用map要超时。。我先开始就这样TLE了。后来看了下后面的discuss,发现要用字典树
于是又自己手动写了个字典树。
所以综上,我们需要:
1、字典树对每一个字符串进行标号
2、并查集判断整个图是否连通
3、判断无向图的欧拉回路是否存在
我的代码:
#include<stdio.h> #include<string.h> #include<algorithm> #define maxn 500005 using namespace std; struct node { int num; node *next[26]; void init(); }; node *root; int father[maxn]; int temp[maxn]; int sum[maxn]; int cnt=0; void node::init() { this->num=0; } int find(int p) { if(father[p]==p) return p; return father[p]=find(father[p]); } void Union(int a,int b) { int x,y; x=find(a); y=find(b); if(x!=y) father[x]=y; } void init() { root= new node; int i; for(i=0;i<26;i++) root->next[i]=NULL; root->init(); } int search(char *s) { int i,len=strlen(s),j; node *p,*t; p=root; for(i=0;i<len;i++) { if(p->next[s[i]-'a']==NULL) { t=new node; for(j=0;j<26;j++) t->next[j]=NULL; t->init(); p->next[s[i]-'a']=t; } p=p->next[s[i]-'a']; } if(p->num==0) { cnt++; return p->num=cnt; } else return p->num; } int main() { int i,a,b; char s1[15],s2[15]; memset(sum,0,sizeof(sum)); for(i=1;i<=maxn;i++) father[i]=i; init(); while(scanf("%s%s",s1,s2)!=EOF) { a=search(s1); b=search(s2); Union(a,b); sum[a]++; sum[b]++; } int NUM=0; for(i=1;i<=cnt;i++) if(father[i]==i) NUM++; if(NUM>1) { printf("Impossible\n"); return 0; } NUM=0; for(i=1;i<=cnt;i++) if(sum[i]&1) NUM++; if(NUM==0||NUM==2) printf("Possible\n"); else printf("Impossible\n"); return 0; }