poj1386

/* * poj1386.cpp * * Created on: 2010-8-13 * Author: friendy */ //并查集加欧拉路 #include #include #include using namespace std; char s[1001]; int f[27], rank[27]; int flag[26], mark[26]; int n; //并查集判连通 void Init() { memset(flag, 0, sizeof(flag)); memset(mark, 0, sizeof(mark)); int i; for (i = 0; i < 26; i++) { f[i] = i; rank[i] = 0; } } int Find(int x) { if (x != f[x]) f[x] = Find(f[x]); return f[x]; } void Union(int i, int j) { int x = Find(i); int y = Find(j); if (x == y) return; if (rank[x] > rank[y]) f[y] = x; else { f[x] = y; if (rank[x] == rank[y]) rank[y]++; } } int solve() { int i; int cnt = 0; for (i = 0; i < 26; i++) {//是否连通,看看出现的字母是不是在同一个集合中 if (mark[i]) { if (f[i] == i) cnt++; if (cnt > 1) return 0; } } int cnt1 = 0, cnt2 = 0; for (i = 0; i < 26; i++) {//判断是否是欧拉路或者回路 if (mark[i]) { if (flag[i] > 1 || flag[i] < -1) return 0; if (flag[i] == 1) cnt1++; if (flag[i] == -1) cnt2++; if (cnt1 > 1 || cnt2 > 1) return 0; } } if (cnt1 ==cnt2)//注意这里不能写成二者都为1,也可能同时为0,前者是欧拉路后者是欧拉回路 return 1; return 0; } int main() { int i, t; int ch1, ch2; scanf("%d", &t); while (t--) { Init(); scanf("%d", &n); getchar(); for (i = 0; i < n; i++) { gets(s); ch1 = s[0] - 'a'; flag[ch1]++; ch2 = s[strlen(s) - 1] - 'a'; flag[ch2]--; Union(ch1, ch2); mark[ch1] = mark[ch2] = 1;//注意要标记一下使用的字母 } if (solve()) { printf("Ordering is possible./n"); } else { printf("The door cannot be opened./n"); } } }

你可能感兴趣的:(2010)