Some of the secret doors contain a very interesting word puzzle. The team of archaeologists has to solve it to open that doors. Because there is no other way to open the doors, the puzzle is very important for us.
There is a large number of magnetic plates on every door. Every plate has one word written on it. The plates must be arranged into a sequence in such a way that every word begins with the same letter as the previous word ends. For example, the word ``acm'' can be followed by the word ``motorola''. Your task is to write a computer program that will read the list of words and determine whether it is possible to arrange all of the plates in a sequence (according to the given rule) and consequently to open the door.
The input consists of T test cases. The number of them (T) is given on the first line of the input file. Each test case begins with a line containing a single integer number Nthat indicates the number of plates (1 <= N <= 100000). Then exactlyNlines follow, each containing a single word. Each word contains at least two and at most 1000 lowercase characters, that means only letters 'a
' through 'z
' will appear in the word. The same word may appear several times in the list.
Your program has to determine whether it is possible to arrange all the plates in a sequence such that the first letter of each word is equal to the last letter of the previous word. All the plates from the list must be used, each exactly once. The words mentioned several times must be used that number of times.
If there exists such an ordering of plates, your program should print the sentence "Ordering is possible.
". Otherwise, output the sentence "The door cannot be opened.
".
32acmibm3acmmalformmouse2okok
The door cannot be opened.Ordering is possible.The door cannot be opened.
#include <iostream> #include <cstring> #include <cstdio> using namespace std; const int MAX = 26+5; int g[MAX][MAX],in[MAX], out[MAX]; int vis[MAX]; void read() { int n; char s[1100]; cin >> n; for(int i=0; i < n; i++) { scanf("%s",s); int u =s[0]-'a'; int v =s[strlen(s)-1]-'a'; in[u]++; out[v]++; g[u][v] = g[v][u]= 1; } } // 判断是否是通路 void dfs(int u) { for(int v=0; v < 26; v++) { if(g[u][v] && !vis[v]) { vis[v] = 1; dfs(v); } } } bool cycle() { int count=0; for(int i=0; i < 26; i++) { if(in[i] || out[i]) if(!vis[i]) { vis[i] = 1; count++; dfs(i); } } // 多于一个强联通分量 if(count>1) return false; return true; } // 欧拉道路的性质 bool euler() { int a=0, b=0; for(int i=0; i < 26; i++) { if(in[i]-out[i]==1) { a++; if(a>1) return false; }else if(out[i]-in[i]==1) { b++; if(b>1) return false; }else if(in[i]!=out[i]){ return false; } } return true; } void init() { memset(g, 0, sizeof(g)); memset(in, 0, sizeof(in)); memset(out, 0, sizeof(out)); memset(vis, 0, sizeof(vis)); } int main() { // freopen("in.txt","r",stdin); int nCase; cin >> nCase; while(nCase--) { init(); read(); if(cycle()) { if(euler()) cout << "Ordering is possible." << endl; else cout << "The door cannot be opened." << endl; }else cout <<"The door cannot be opened." << endl; } return 0; }
连通的无向图 有欧拉路径的充要条件是:中奇顶点(连接的边数量为奇数的顶点)的数目等于0或者2。
连通的无向图 是欧拉环(存在欧拉回路)的充要条件是:中每个顶点的度都是偶数。
连通无向图有欧拉路径的充要条件也可以写作“图中奇顶点数目不多于2个”,这是因为奇顶点数目不可能是1个。实际上,连通无向图中,奇顶点的数目总是偶数。
对于不连通的无向图,如果有两个互不连通的部分都包含至少一条边,那么显然不能一笔画。只有当此图的边全都在某一个连通部分中(即其它的连通部分都是一个个孤立的顶点,度数为0),并满足连通无向图关于一笔画的充要条件,而该图才能一笔画。也即是说,可以一笔画的(无向)图如果不是连通图,就必定是一个可以一笔画的连通图与若干个孤立顶点的组合。
除了用顶点的度数作为判定的充要条件,还可以用图中边的特性来作为欧拉回路存在的判定准则。连通的无向图 中存在欧拉回路,等价于图所有的边可以划分为若干个环的不交并。具体来说,等价于存在一系列的环,使得图里的每一条边都恰好属于某一个环。
1.对于上题中的在判断是否符合欧拉路径的时候用到了3个条件,
一是存在一个点入度减去出度为1,即终点,
二.出度减去入度为1,即起点。
三. 其余的点都是出度等于入度