ZOJ 2016 Play on Words (HDU 1116)(欧拉回路,欧拉通路)

我去啊,这就是欧拉路啊,并查集时没注意看,还以为很复杂呢……

媛神的总结,言简意赅,一点都不用改:

 

 

欧拉回路,所有点连通,并且所有点的入度等于出度。 

欧拉通路。从原点S出发,经过所有点,从终点t出去。 

所有点除起点终点外的度都是偶数,且出度等于入度

起点的出度比入度大1 

终点的入度比出度大1 

 

 

#include<stdio.h> #include<string.h> #include<math.h> #define N 30 int father[N],vis[N]; int findx(int x) { if(father[x]!=x) father[x]=findx(father[x]); return father[x]; } void merge(int a,int b) { int x,y; x=findx(a); y=findx(b); if(x!=y) father[x]=y; } int main() { int text,cnt,i,j,n,out[N],in[N],p[30],a,b; char str[1001]; scanf("%d",&text); while(text--) { scanf("%d",&n); memset(out,0,sizeof(out)); memset(in,0,sizeof(in)); memset(vis,0,sizeof(vis)); for(i=0;i<26;i++) father[i]=i; while(n--) { scanf("%s",str); a=str[0]-'a'; b=str[strlen(str)-1]-'a'; merge(a,b); out[a]++; in[b]++; vis[a]=1; vis[b]=1; } for(i=0;i<26;i++) father[i]=findx(i); for(cnt=0,i=0;i<26;i++) if(vis[i] && father[i]==i) cnt++; if(cnt>1) //图不连通 { printf("The door cannot be opened./n"); continue; } for(j=0,i=0;i<26;i++) if(vis[i] && out[i]!=in[i]) p[j++]=i; if(j==0) {//欧拉回路,即环 printf("Ordering is possible./n"); continue; } if(j==2 && ( out[p[0]]-in[p[0]]==1 && in[p[1]]-out[p[1]]==1 || out[p[1]]-in[p[1]]==1 && in[p[0]]-out[p[0]]==1 ) ) {//欧拉通路 printf("Ordering is possible./n"); continue; } printf("The door cannot be opened./n"); } return 0; } 

 

你可能感兴趣的:(merge)