POJ 2513 Colored Sticks
这题让我明白了POJ原来多组数据测试是这么回事啊!!
大致题意:
给定一些木棒,木棒两端都涂上颜色,求是否能将木棒首尾相接,连成一条直线,要求不同木棒相接的一边必须是相同颜色的。
解题思路:
木棒相当于边,两端相当于两个节点,建图,判断是否联通,是否是欧拉图。
建图并使用并查集判断联通时需要字典树,不能用map,会超时的(吐槽它为什么这么慢!!!)。
当无向图的奇度数节点没有或只有两个时,就是欧拉图。
下面是代码:
#include <stdio.h> #include <map> #include <string.h> #include <stdlib.h> using namespace std; int a[500005],d[500005],cut; struct node { char s; int c; struct node *next[26]; } head; char s[2][15]; int find1(int x) { while(a[x]!=x) { x=a[x]; } return x; } int build(int n) { int len=strlen(s[n]),i,j; struct node *p,*q; p=&head; for(i=0; i<len-1; i++) { if(p->next[s[n][i]-'a']==NULL) { q=(struct node *)malloc(sizeof(struct node)); for(j=0; j<26; j++) { q->next[j]=NULL; } q->c=-1; p->next[s[n][i]-'a']=q; p=q; } else { p=p->next[s[n][i]-'a']; } } if(p->next[s[n][len-1]-'a']==NULL) { q=(struct node*)malloc(sizeof(struct node)); for(j=0; j<26; j++) { q->next[j]=NULL; } q->c=cut; cut++; p->next[s[n][i]-'a']=q; p=q; return q->c; } else { p=p->next[s[n][i]-'a']; if(p->c==-1) { p->c=cut; cut++; } return p->c; } } int main() { int x,y,i; for(i=0; i<26; i++) { head.next[i]=NULL; } for(i=0; i<500005; i++) { a[i]=i; d[i]=0; } cut=0; while(scanf("%s%s",s[0],s[1])!=EOF) { x=build(0); y=build(1); a[find1(x)]=a[find1(y)]; d[x]++; d[y]++; } if(cut==0) { printf("Possible\n"); return 0; } int flat=0; for(i=0; i<cut; i++) { if(a[i]==i) { flat++; } } if(flat==1) { flat=0; for(i=0; i<cut; i++) { if(d[i]%2) { flat++; } } if(flat==0||flat==2) { printf("Possible\n"); } else { printf("Impossible\n"); } } else { printf("Impossible\n"); } return 0; }