UVA

来源:互联网 发布:阿里云搭ss 编辑:程序博客网 时间:2024/06/10 05:29
/*  把字母看作结点,单词看成有向边,则,问题有解,当且仅当图中有欧拉路径    存在欧拉道路的条件,见小白书 P169    判断连通的方法有两种: 1. DFS 2. 并查集*/


#include <iostream>#include <vector>#include <string>#include <cstring>using namespace std;const int N = 256;int used[N]; // 是否出现过int deg[N]; // 度数 int pa[N];int find ( int x ){return pa[x] != x ? pa[x] = find (pa[x]) : x;}void init() //初始化数组,初始化并查集 {memset( used, 0, sizeof(used) );memset( deg, 0, sizeof(deg) );for (int ch = 'a'; ch <= 'z'; ch++)pa[ch] = ch;}int main(){int t;cin >> t;while (t--){int n;string word;cin >> n;init();int cc = 26; // 连通块个数for (int i = 0; i < n; i++){cin >> word;char c1 = word[0], c2 = word[ (int)word.size() - 1];deg[c1]++;deg[c2]--;used[c1] = used[c2] = 1;int s1 = find(c1), s2 = find(c2);if (s1 != s2){pa[s1] = s2;cc--;}}vector<int> v;for (int ch = 'a'; ch <= 'z'; ch++){if (!used[ch]) cc--; //没出现过的字母else if (deg[ch] != 0) v.push_back(deg[ch]); }bool ok = false;if ( cc == 1 && ( v.empty() || ( v.size() == 2 && ( v[0] == 1 || v[0] == -1) ) ) ) ok = true;if (ok) cout << "Ordering is possible.";else cout << "The door cannot be opened.";cout << endl;}}