---恢复内容开始---
把它看成是一个图
只是需要欧拉路径就可以了 首尾能连成一条线即可
如果要判断这个图是否连通 得用并查集
在hrbust oj里面看答案学到的方法 不用各种for循环套着判断能否循环
只需要在union的时候做做调整 让比较大的父亲节点的父亲节点等于小的父亲节点 向1靠拢就可以
但是在这里面 是向出现过的最小的字母的排序靠拢 所以要记录
而且for循环26个字母的时候 只对出现过的字母做判断它是否与最小的字母可以连通
#include<stdio.h> #include<string.h> #include<algorithm> #include<map> using namespace std; int ru[30]; int chu[30]; int fa[30]; int vis[30]; void init() { for(int i=1;i<=26;i++) { ru[i]=0; chu[i]=0; fa[i]=i; vis[i]=0; } } int find(int i) { return fa[i]==i?i:find(fa[i]); } void un(int a,int b) { int aa=find(a); int bb=find(b); if(aa>bb) fa[aa]=bb; else fa[bb]=aa; } int main(){ int t; scanf("%d",&t); while(t--) { int n; scanf("%d",&n); char s[2000]; init(); int minn=26; for(int i=0;i<n;i++) { scanf("%s",s); int a=s[0]-‘a‘+1; int len=strlen(s); int b=s[len-1]-‘a‘+1; chu[a]++; ru[b]++; un(a,b); vis[a]++; vis[b]++; if(a<minn) minn=a; if(b<minn) minn=b; } int yi=0; int er=0; int san=0; bool ok=true; for(int i=1;i<=26;i++) { if(ru[i]==chu[i]) yi++; else if(ru[i]==chu[i]+1) er++; else if(ru[i]==chu[i]-1) san++; if(vis[i]!=0) { if(find(i)!=minn) ok=false; } } if(yi==24&&er==1&&san==1&&ok==true) printf("Ordering is possible.\n"); else if(yi==26&&ok==true) printf("Ordering is possible.\n"); else printf("The door cannot be opened.\n"); } }
---恢复内容结束---
原文:http://www.cnblogs.com/rayrayrainrain/p/5188521.html