http://acm.hdu.edu.cn/showproblem.php?pid=1116
题意:判断n个单词是否可以相连成一条链或一个环,两个单词可以相连的条件是 前一个单词的最后一个字母和后一个单词的第一个字母一样。
分析前提:有(无)向图的欧拉路径判断均是基于连通图
欧拉路径判断:
1、一个无向图存在欧拉路径的充要条件:头节点和尾节点度数为奇数 ;中间节点度数为偶数。
2、一个有向图存在欧拉路径的充要条件:头 入度==出度-1 ;中间 入度==出度 ; 尾 入度==出度+1。
欧拉回路判断:
1、一个无向图存在欧拉回路的充要条件:当且仅当该图所有顶点度数都是偶数。
2、一个有向图存在欧拉回路的充要条件:所有顶点的入度等于出度。
#include<cstdio> #include<cstring> int fa[26],in[26],out[26]; int findset(int x) { if(fa[x]==x) return fa[x]; return fa[x]=findset(fa[x]); } bool vis[26]; char s[1010]; int main() { int T,n; scanf("%d",&T); while(T--){ scanf("%d",&n); getchar(); memset(in,0,sizeof(in)); memset(out,0,sizeof(out)); memset(vis,0,sizeof(vis)); for(int i=0;i<26;i++) fa[i]=i; while(n--){ gets(s); int x=s[0]-'a'; out[x]++; int y=s[strlen(s)-1]-'a'; in[y]++; fa[y]=findset(x); vis[x]=vis[y]=1; } int scc=0; for(int i=0;i<26;i++){ if(vis[i]&&fa[i]==i) scc++; } if(scc>1){//如果不连通 printf("The door cannot be opened. "); continue; } bool flag=false; int x=0,y=0,z=0; for(int i=0;i<26;i++){ if(vis[i]&&in[i]!=out[i]){ if(in[i]==out[i]+1) x++; else if(in[i]+1==out[i]) y++; else z++; } } if(z){ printf("The door cannot be opened. "); continue; } if((x==1&&y==1)||(x==0&&y==0)){ printf("Ordering is possible. "); continue; } else printf("The door cannot be opened. "); } return 0; }