hdu-1116(欧拉回路+并查集)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1116
思路:将字符串的头元素和尾元素视为图的x,y节点,然后合并x,y。
如果这个图不连通,则门不能打开,如果路径是欧拉回路或者欧拉通路,则门可以打开。
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int a[50],b[50],vis[50],in[50],out[50]; char str[1200]; int f(int x) { if(x==a[x]) return a[x]; else { a[x]=f(a[x]); return a[x]; } } void Merge(int x,int y) { int t1=f(x),t2=f(y); if(t1!=t2) { a[t2]=t1; } } int main(void) { int num,i,j,x,y,t,n; scanf("%d",&t); while(t--) { scanf("%d",&n); for(i=0;i<26;i++) { a[i]=i;vis[i]=0; b[i]=0;in[i]=0;out[i]=0; } for(j=0;j<n;j++) { scanf("%s",str); x=str[0]-'a'; y=str[strlen(str)-1]-'a'; Merge(x,y); in[y]++;out[x]++; vis[x]=1;vis[y]=1; } for(i=0;i<26;i++) a[i]=f(i); num=0; for(i=0;i<26;i++) if(vis[i]&&a[i]==i) num++; if(num>1) { printf("The door cannot be opened.\n"); } else { num=0; for(i=0;i<26;i++) if(vis[i]&&in[i]!=out[i]) b[num++]=i; if(num==0) { printf("Ordering is possible.\n"); } else if(num==2&&(out[b[0]]-in[b[0]]==1&&in[b[1]]-out[b[1]]==1|| out[b[1]]-in[b[1]]==1&&in[b[0]]-out[b[0]]==1)) printf("Ordering is possible.\n"); else printf("The door cannot be opened.\n"); } } return 0; }