HDU 1116 Play on Words(有向图的欧拉路)
首先这个题,我以为是DFS。。。交上各种TLE ,RE,暴栈和超时啊。。。找了一下题解,发现是图论问题。。。唉。
又重新翻离散课本。。。定理:有向图的欧拉路连通且存在一个出度比入度大一的,存在一个入度比出度大一的,其他入度出度相等。有向图欧拉回路连通且入度出度都相等。
交上WA,然后查错,总以为是 判断是否是联通的时候做错了,其实是 忘记判断也是欧拉回路了。。。悲剧。。。代码 好烂。
#include <stdio.h> #include <string.h> #include <stdlib.h> int p[27][27],z,n,o[27],key[27]; int find(int x) { int r,t; r = x; while(x != o[x]) x = o[x]; while(r != x) { t = o[r]; o[r] = x; r = t; } return x; } void merge(int x,int y) { x = find(x); y = find(y); if(x != y) o[x] = y; } int main() { int t,i,j,sum,start,end,len,sum1,sum2,k1,k2; char str[1001]; scanf("%d%*c",&t); while(t--) { z = 1;k1 = k2 = 0; memset(p,0,sizeof(p)); memset(key,0,sizeof(key)); for(i = 1;i <= 26;i ++) o[i] = i; scanf("%d%*c",&n); for(i = 1;i <= n;i ++) { scanf("%s",str); len = strlen(str); start = str[0] - 'a'+1; end = str[len-1] - 'a'+1; key[start] = key[end] = 1; merge(start,end); p[start][end] ++; } for(i = 1;i <= 26;i ++) { if(key[i]) break; } sum = find(i); for(j = i+1;j <= 26;j ++) { if(find(j) != sum && key[j]) break; } if(j != 27) z = 0; for(i = 1;i <= 26&&z;i ++) { sum1 = sum2 = 0; for(j = 1;j <= 26;j ++) { sum1 += p[i][j]; sum2 += p[j][i]; } if(sum1 == sum2) ; else if(sum1 == sum2+1) { k1++; } else if(sum1+1 == sum2) { k2 ++; } else { z = 0; break; } } if(z) { if(k1==1&&k2==1) printf("Ordering is possible.\n"); else if(k1==0&&k2==0) printf("Ordering is possible.\n"); else printf("The door cannot be opened.\n"); } else printf("The door cannot be opened.\n"); } return 0; }