欧拉路径是指能从一个点出发能够“一笔画”完整张图的路径;(每条边只经过一次而不是点)
在无向图中:如果每个点的度都为偶数 那么这个图是欧拉回路;如果最多有2个奇数点,那么出发点和到达点必定为
该2点,那么这个路径就为欧拉路;(前提都是该图连通)
在有向图中:如果每个店的出度和入度都相同,那么为欧拉回路;如果最多只能有2个点的出度不等于入度,并且其中
一个点的 入度=出度+1,另一点的 入度+1=出度,那么为欧拉路;(前提图连通)
//因为字符从第一个到最后一个,所以用有向图 #include<stdio.h> #include<string.h> #include<stack> using namespace std; char ch[1003]; int map[1003][1003],n,m,pa[10003]; int r[10003],c[10003],vis[10003]; stack<int>s; void inint() { int i; for(i=1;i<=26;i++) { pa[i]=i; } } int find(int x) { if(x!=pa[x]) pa[x]=find(pa[x]); return pa[x]; } int main() { int i,j; int t; scanf("%d",&t); while(t--) { scanf("%d",&m); memset(vis,0,sizeof(vis)); inint(); memset(r,0,sizeof(r)); memset(c,0,sizeof(c)); memset(map,0,sizeof(map)); for(i=0;i<m;i++) { scanf("%s",&ch); int l=strlen(ch); map[ch[0]-'a'+1][ch[l-1]-'a'+1]=1; r[ch[0]-'a'+1]++;c[ch[l-1]-'a'+1]++; int x,y; x=find(ch[0]-'a'+1); y=find(ch[l-1]-'a'+1); vis[ch[0]-'a'+1]=1; vis[ch[l-1]-'a'+1]=1; if(x!=y) pa[x]=y; } int sum=0; for(i=1;i<=26;i++) { if(pa[i]==i&&vis[i]) { sum++; } if(sum>1) break; } if(sum>1) //未连通 { printf("The door cannot be opened. "); continue; } sum=0; for(i=1;i<=26;i++) { if(vis[i]&&(c[i]!=r[i]))//寻找出度入度不相同的点 { sum++; s.push(i); } } if(sum>2)//多余2个 printf("The door cannot be opened. "); else if(sum==0)//出度入度全相同 printf("Ordering is possible. "); else if(sum==2) { int x1,x2; x1=s.top(); s.pop(); x2=s.top(); s.pop(); if((c[x1]+1==r[x1])&&(c[x2]==r[x2]+1)||(c[x2]+1==r[x2])&&(c[x1]==r[x1]+1))//判断是否条件成立 { printf("Ordering is possible. "); } else printf("The door cannot be opened. "); } else printf("Ordering is possible. "); } }