您的位置:首页 > 其它

Uva - 10129 - Play on Words

2015-06-17 14:54 387 查看


把单词收尾字母当作每条边的起点和终点,就抽象为一个有向图,判断有向图是否存在欧拉路。用到图论的知识,有向图最多只能有两个点的入度不等于出度,而且起点必须是出度恰好比入度大1,终点入度比出度大1,并且有向图的无向图是连通的。判断连通性用dfs方法判断。

AC代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cstring>
#include <string>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <algorithm>
#include <stack>
#include <queue>
#include <bitset>
#include <cassert>

using namespace std;

const int maxv = 26;
const int maxn = 1005;

int G[maxv][maxv];
int inDeg[maxv]; // 每个点的入度数
int outDeg[maxv]; // 每个点的出度数
int vis[maxv];

void dfs(int u)
{
vis[u] = true;
for (int i = 0; i < maxv; i++) {
if (G[u][i] > 0) {
G[u][i]--;
G[i][u]--;
dfs(i);
}
}
}

// 判断度数是否满足
bool okDeg()
{
bool star = false;
bool end = false;

for (int i = 0; i < maxv; i++) {
if (inDeg[i] != outDeg[i]) {
if (!end && inDeg[i] == outDeg[i] + 1) { // 终点
end = true;
}
else if (!star && inDeg[i] + 1 == outDeg[i]) { // 起点
star = true;
}
else {
return false;
}
}
}
return true;
}

bool okDfs()
{
for (int u = 0; u < maxv; u++) {
if (inDeg[u] + outDeg[u]) {
if (vis[u] == false) {
return false;
}
}
}

return true;
}

int main()
{
ios::sync_with_stdio(false);
int T;
cin >> T;
while (T--) {
memset(G, 0, sizeof(G));
memset(inDeg, 0, sizeof(inDeg));
memset(outDeg, 0, sizeof(outDeg));
memset(vis, 0, sizeof(vis));

int edge, star;
cin >> edge;
while (edge--) {
char ch[maxn];
cin >> ch;
int u = ch[0] - 'a';
int v = ch[strlen(ch) - 1] - 'a';
inDeg[u]++;
outDeg[v]++;
G[u][v]++;
G[v][u]++;
star = u;
}

dfs(star);
if (okDfs() && okDeg()) {
cout << "Ordering is possible.\n";
}
else {
cout << "The door cannot be opened.\n";
}
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: