[POJ 1386] Play on Words
[题目链接]
http://poj.org/problem?id=1386
[算法]
将每个单词的首字母向尾字母连一条有向边,判断欧拉路径是否存在,即可
[代码]
#include <algorithm> #include <bitset> #include <cctype> #include <cerrno> #include <clocale> #include <cmath> #include <complex> #include <cstdio> #include <cstdlib> #include <cstring> #include <ctime> #include <deque> #include <exception> #include <fstream> #include <functional> #include <limits> #include <list> #include <map> #include <iomanip> #include <ios> #include <iosfwd> #include <iostream> #include <istream> #include <ostream> #include <queue> #include <set> #include <sstream> #include <stdexcept> #include <streambuf> #include <string> #include <utility> #include <vector> #include <cwchar> #include <cwctype> #include <stack> #include <limits.h> using namespace std; #define MAXN 100010 #define MAXLEN 1010 #define MAXC 30 const int M = 100000; struct edge { int to,nxt; } e[MAXN]; int tot; int fa[MAXC],head[MAXC],size[MAXC],in[MAXC],out[MAXC]; char str[MAXLEN]; set< int > s; template <typename T> inline void read(T &x) { int f = 1; x = 0; char c = getchar(); for (; !isdigit(c); c = getchar()) if (c == '-') f = -f; for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0'; x *= f; } inline void addedge(int u,int v) { tot++; e[tot] = (edge){v,head[u]}; head[u] = tot; } inline int get_root(int x) { if (fa[x] == x) return x; return fa[x] = get_root(fa[x]); } inline void merge(int u,int v) { int x = get_root(u) , y = get_root(v); if (x == y) return; if (size[x] < size[y]) swap(x,y); // Union By Rank size[x] += size[y]; fa[y] = x; } int main() { int T; read(T); while (T--) { int n; read(n); for (int i = 1; i <= 26; i++) { head[i] = 0; fa[i] = i; size[i] = 1; in[i] = out[i] = 0; } s.clear(); for (int i = 1; i <= n; i++) { scanf("%s",str + 1); int len = strlen(str + 1); int fir = str[1] - 'a' + 1 , lst = str[len] - 'a' + 1; merge(fir,lst); addedge(fir,lst); in[lst]++; out[fir]++; s.insert(fir); s.insert(lst); } bool connect = false; int sz = (int)s.size(); for (int i = 1; i <= 26; i++) connect |= (size[i] == sz); if (!connect) { printf("The door cannot be opened.\n"); continue; } bool flag = true; for (set<int> :: iterator it = s.begin(); it != s.end(); it++) flag &= (in[*it] == out[*it]); if (flag) { printf("Ordering is possible.\n"); continue; } int s1 = 0 , s2 = 0; for (set<int> :: iterator it = s.begin(); it != s.end(); it++) { s1 += ((in[*it] - out[*it]) == 1); s2 += ((out[*it] - in[*it]) == 1); if (abs(in[*it] - out[*it]) >= 2) s1 = M; } if (s1 == s2 == 1) printf("Ordering is possible.\n"); else printf("The door cannot be opened.\n"); } return 0; }