題目連接:https://vjudge.net/problem/UVA-10129css
代碼以下:算法
// UVa10129 Play on Words // Rujia Liu // 題意:輸入n個單詞,是否能夠排成一個序列,使得每一個單詞的第一個字母和上一個單詞的最後一個字母相同 // 算法:把字母看做結點,單詞當作有向邊,則有解當且僅當圖中有歐拉路徑。注意要先判連通 #include<cstdio> #include<cstring> #include<vector> using namespace std; const int maxn = 10000 + 5; int pa[256], used[256], deg[256]; // 是否出現過;度數 char word[maxn]; int n, cc; int findset(int x) { return ( pa[x] != x ? pa[x] = findset(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; // 初始化並查集 cc = 26; // 連通塊個數 } void solve() { scanf("%d", &n); for(int i = 0; i < n; i++) { scanf("%s", word); char c1 = word[0]; char c2 = word[strlen(word)-1]; deg[c1]++; deg[c2]--; used[c1] = used[c2] = 1; int s1 = findset(c1); int s2 = findset(c2); if(s1 != s2) { pa[s1] = s2; cc--; } } vector<int> d; for(int ch = 'a'; ch <= 'z'; ch++) { if(!used[ch]) cc--; // 沒出現過的字母 else if(deg[ch] != 0) d.push_back(deg[ch]); } int ok = false; if(cc == 1 && (d.empty() || (d.size() == 2 && (d[0] == 1 || d[0] == -1)))) ok = true; if(ok) printf("Ordering is possible.\n"); else printf("The door cannot be opened.\n"); } int main() { int T; scanf("%d", &T); while(T--) { init(); solve(); } return 0; }