UVA 10129 单词

来源:互联网 发布:大秀直播程序源码 编辑:程序博客网 时间:2024/06/05 11:27

欧拉回路:最先由著名的七桥问题提出,如果一个无向图是连通的,且最多只有两个奇点,则一定存在欧拉回路。

如果有两个奇点,则必须从其中一个奇点出发,另一个奇点终止,如果奇点不存在,则可以从任意点出发,最终一定会回到该点(称为欧拉道路)

 最多只能有两个点的入度不等于出度,而且最终必须是其中一个点的出度恰好比入度大1(把它作为起点),另一个入度比出度大1(把它作为终点)。当然前提条件是:在忽略边的方向后,图必须是连通的。

参考:http://www.ackratos.com/blog/?p=368

本题技巧:不采用单词作为结点建模,否则数据量会非常大(100000),采用26个小写字母作为图的结点,避免造成空间过大。首先采用深度优先搜索判断图的连通性,然后再根据上述准则看是否存在欧拉回路。

#include<iostream>#include<cstdio>#include<cstring>#include<memory>#include<queue>#include<algorithm>#include<string>#include<cmath>using namespace std;///#define Maxn 26bool maze[Maxn][Maxn];int inEdges[Maxn];int outEdges[Maxn];bool vis[Maxn];int nWords;int nLetters;bool dfs(int start, int total){if (total == nLetters)return true;int i;vis[start] = true;for (i = 0; i < Maxn; i++){if (maze[start][i] && !vis[i]){if (dfs(i, total + 1))return true;}}return false;}int main(){///int i, j;int nCases;cin >> nCases;while (nCases--){nLetters = 0;memset(maze, 0, sizeof(maze));memset(inEdges, 0, sizeof(inEdges));memset(outEdges, 0, sizeof(outEdges));memset(vis, 0, sizeof(vis));cin >> nWords;for (i = 0; i < nWords; i++){char sLetter, eLetter, buffer[1010];cin >> buffer;sLetter = buffer[0] - 'a';eLetter = buffer[strlen(buffer) - 1] - 'a';maze[sLetter][eLetter] = true;inEdges[eLetter]++;outEdges[sLetter]++;if (!vis[sLetter]){vis[sLetter] = true;nLetters++;}if (!vis[eLetter]){vis[eLetter] = true;nLetters++;}}memset(vis, 0, sizeof(vis));int pos = 0;for (pos = 0; pos < Maxn; pos++){if (inEdges[pos] != 0 || outEdges[pos] != 0)break;}if (!dfs(pos, 1)){cout << "The door cannot be opened." << endl;continue;}int nSpecial = 0;for (i = 0; i < Maxn; i++){if (inEdges[i] != 0 || outEdges != 0){if (inEdges[i] - outEdges[i] == 1 || outEdges[i] - inEdges[i] == 1)nSpecial++;else{if (inEdges[i] != outEdges[i]){nSpecial = -1;break;}}}}if(nSpecial ==0 || nSpecial == 2)            cout << "Ordering is possible." << endl;        else            cout << "The door cannot be opened." << endl;}///    return 0;}