UVA 10441 - Catenyms(欧拉道路)

来源:互联网 发布:翡翠台直播软件apk 编辑:程序博客网 时间:2024/04/29 18:26

UVA 10441 - Catenyms

题目链接

题意:给定一些单词,求拼接起来,字典序最小的,注意这里的字典序为一个个单词比过去,并不是一个个字母

思路:欧拉回路,利用并查集判联通,然后欧拉道路判定,最后dfs输出路径

代码:

#include <cstdio>#include <cstring>#include <string>#include <vector>#include <iostream>#include <algorithm>using namespace std;const int N = 30;vector<string> g[N];vector<string> ans;int t, n, parent[N];bool used[N][1005];int find(int x) {return parent[x] == x ? x : parent[x] = find(parent[x]);}int vis[N];int cnt, tot, ru[N], chu[N];void init() { memset(ru, 0, sizeof(ru));memset(chu, 0, sizeof(chu));memset(vis, 0, sizeof(vis));memset(used, 0, sizeof(used));for (int i = 0; i < 26; i++) {g[i].clear();parent[i] = i;}cnt = 1; tot = 0;scanf("%d", &n);string s;while (n--) {cin >> s;int u = s[0] - 'a', v = s[s.length() - 1] - 'a';if (!vis[u]) {vis[u] = 1; tot++;}if (!vis[v]) {vis[v] = 1; tot++;}ru[v]++; chu[u]++;g[u].push_back(s);int pu = find(u);int pv = find(v);if (pu != pv) {parent[pu] = pv;cnt++;}}for (int i = 0; i < 26; i++)sort(g[i].begin(), g[i].end());}void dfs(int u) {for (int i = 0; i < g[u].size(); i++) {int v = g[u][i][g[u][i].length() - 1] - 'a';if (used[u][i]) continue;used[u][i] = 1;dfs(v);ans.push_back(g[u][i]);}}bool solve() {if (cnt != tot) return false;int Min = 30;int odd = 0, st;for (int i = 0; i < 26; i++) {if (g[i].size()) Min = min(Min, i);if (ru[i] - chu[i] == -1) {odd++;st = i;}else if (chu[i] - ru[i] == -1)odd++;else if (chu[i] != ru[i]) return false;if (odd > 2) return false;}ans.clear();if (!odd) dfs(Min);else dfs(st);for (int i = ans.size() - 1; i > 0; i--)cout << ans[i] << ".";cout << ans[0] << endl;return true;}int main() {scanf("%d", &t);while (t--) {init();if (!solve()) printf("***\n");}return 0;}


1 0
原创粉丝点击