HDU 1116 Play on Words
欧拉回路 (并查集)
#include<cstring> #include<iostream> #include<cstdio> #include<cmath> using namespace std; const int MAXN = 30; bool vis[MAXN]; int in[MAXN], out[MAXN], bin[MAXN]; int findx(int x) { return x==bin[x]?x:findx(bin[x]);//通过三目运算符简化写法
/*
while(bin[x]!=x)
x = bin[x];
return x;
*/
} void join(int a, int b) { int x , y; x = findx(a); y = findx(b); if(x != y) bin[y]=x; } int main() { int t, n; int l, r, i; char str[1005]; int wordnum, len; int root; bool flag, flag1; int innum, outnum; int start, end; scanf("%d", &t); while(t--) { memset(vis, 0, sizeof(vis)); memset(in, 0 ,sizeof(in)); memset(out, 0, sizeof(out)); for(i=1;i<MAXN;i++) bin[i]=i; flag = flag1 = true; innum = outnum = root = 0; scanf("%d", &wordnum); for(i=1;i<=wordnum;i++) { scanf("%s", str); len = strlen(str); start = str[0] - 'a' + 1; end = str[len-1] - 'a' + 1; vis[start] = true; vis[end] = true; out[start]++; in[end]++; join(start, end); } for(i=1;i<MAXN;i++)//欧拉路径的条件判断入度等于出度, 如果不相等,那就是
//存在小于等于一对in,out互相相差一,否则就是不存在 { if(vis[i]) { if(bin[i]==i) root++; if(in[i]!=out[i]) { if(in[i]-out[i]==1) innum++; else if(out[i]-in[i]==1) outnum++; else flag1=false; } } if(root>1)//最后的根是否只有一个,如果有多个根说明没有遍历完全部的单词 { flag = false; break; } } if(flag&&flag1&&((innum==0&&outnum==0)
||(innum==1&&outnum==1))) printf("Ordering is possible.\n"); else printf("The door cannot be opened.\n"); } return 0; }