poj 1386 Play on Words

/* Name: poj 1386 Play on Words Author: UnimenSun Date: 08/06/11 15:43 Description:欧拉路径&欧拉回路 */ /* 解题报告: 有向图存在欧拉回路的条件: 1、所有结点为的入度等于出度 有向图存在欧拉路径的条件: 1、仅存在两个结点:其中一个入度比出度大一,另一个出度比入度大一 2、其于的点入度与出度相等 另外须同时保证图在去掉方向后边通的 注:只需这样判断:在去掉方向性判断图的连通性,并判断图中各顶点的度数即可 */ #include <iostream> #include <cstdio> #include <cstring> #include <vector> using namespace std; int t, n; int g[26][26], indegree[26], outdegree[26]; vector<int> letter; int visited[26]; void floyd() { for(int k=0; k<26; ++k) for(int i=0; i<26; ++i) for(int j=0; j<26; ++j) { if(g[i][k] && g[k][j]) g[i][j] = 1; } } //判断图的连通性 bool JudageConnect() { floyd(); for(int i=0; i<letter.size(); ++i) { if(!g[letter[0]][letter[i]]) return false; } return true; } //判断度数 bool JudgeDegree() { bool circle = true; int nInde = 0; int nOutDe = 0; for(int i=0; i<letter.size(); ++i) { int x = letter[i]; if(1 == indegree[x] - outdegree[x]) { circle = false; nInde++; } else if(1 == outdegree[x] - indegree[x]) { circle = false; nOutDe++; } else if(indegree[x] != outdegree[x]) { return false; } } if(circle) return true; if(1 == nInde && 1 == nOutDe) return true; return false; } int main() { char word[1001]; scanf("%d", &t); while(t--) { //初始化 memset(g, 0, sizeof(g)); memset(indegree, 0, sizeof(indegree)); memset(outdegree, 0, sizeof(outdegree)); memset(visited, 0, sizeof(visited)); letter.clear(); //读入数据并建图 scanf("%d", &n); while(n--) { scanf("%s", word); int nFirst = word[0] - 'a'; int nLast = word[strlen(word) - 1] - 'a'; g[nFirst][nLast] = g[nLast][nFirst] = 1; outdegree[nFirst]++; indegree[nLast]++; if(!visited[nFirst]) { visited[nFirst] = 1; letter.push_back(nFirst); } if(!visited[nLast]) { visited[nLast] = 1; letter.push_back(nLast); } } if(JudageConnect() && JudgeDegree()) printf("Ordering is possible./n"); else printf("The door cannot be opened./n"); } return 0; }

你可能感兴趣的:(poj 1386 Play on Words)