/** 欧拉道路 1>.有向图忽略方向得到的无向图 是不是连通 2>.所有点的入度等于出度 或者 只有两个点的入度不等于出度,且一个入度比出度大一,另一个入度比出度小一 */ #include<iostream> #include<cstdio> #include<cstring> using namespace std; int r[30]; int find_(int x) { while(x!=r[x]) x=r[x]; return x; } int main() { int T,n,x,y,i,ok; char a[1005]; int in[30],out[30]; scanf("%d",&T); while(T--){ scanf("%d",&n); memset(r,-1,sizeof(r) ); memset(in,0,sizeof(in) ); memset(out,0,sizeof(out) ); while(n--){ scanf("%s",a); int m=strlen(a); int p=a[0]-'a',q=a[m-1]-'a'; in[p]++; out[q]++; if(r[p]==-1) r[p]=p; if(r[q]==-1) r[q]=q; x=find_(p); y=find_(q); if(x!=y) r[x]=y; } int jud=0; for(i=0;i<26;i++) /// 并查集判断 有向图忽略方向得到的无向图 是不是连通 if(r[i]==i) jud++; if(jud==1) ok=1; else ok=0; if(ok){ int m[30],ans=0; for(i=0;i<26;i++){ if(in[i]!=out[i]){ /// 入度不等于回路 ans++; m[ans]=i; } } if(!ans) ok=1; /// 所有点的入度等于出度 else if(ans==2){ /// 只有两个点的入度不等于出度 且 一个入度比出度大一 另一个入度比出度小一 if(in[m[1]]-out[m[1]]==1 && in[m[2]]-out[m[2]]==-1) ok=1; else if(in[m[1]]-out[m[1]]==-1 && in[m[2]]-out[m[2]]==1) ok=1; else ok=0; } else ok=0; } if(ok) printf("Ordering is possible.\n"); else printf("The door cannot be opened.\n"); } return 0; }
原文:http://blog.csdn.net/u014705854/article/details/43783027