Transmission Door
Words1-play on Words#graph-theory #euler-circuit
Some of the secret doors contain a very interesting word puzzle. The team of archaeologists have to solve it to open that doors. Because There is no other-a-to-open the doors, the puzzle is very important for us.
There is a large number of magnetic plates on every door. Every plate have one word written on it. The plates must be arranged to a sequence in such a-to-every word begins with the same-letter as the previous word Ends. For example, the word ACm' Can is followed by the word motorola '. Your task is to write a computer program that would read the list of words and determine whether it's possible to arrange All of the plates in a sequence (according to the given rule) and consequently to open the door.
Input
The input consists of T test cases. The number of them ( T , equal to about) was given on the first line of the input file. Each test case is begins with a line containing a, a single integer number, that indicates the number of N plates ( 1 <= N <= 100000 ). Then exactly N lines follow, each containing a single word. Each of the word contains at least-lowercase characters, which means only letters ' through ' a
z
wil L appear in the word. The same word may appear several times in the list.
Output
Your program have to determine whether it's possible to arrange all the plates in a sequence such that's the first letter of Each word was equal to the last letter of the previous word. The plates from the list must is used, each exactly once. The words mentioned several times must is 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.
".
Example
Sample input:32acmibm3acmmalformmouse2okoksample output:the door cannot be opened. Ordering is possible. The door cannot be opened.
-----------------------------------------------------
The title requires that all words be arranged into such that first letter of every word is equal to the last letter of the previous word. This problem is a typical Euler path problem, which is difficult to analyze.
We consider how toBuilding Map
Consider 26 letters as nodes, and each word as a forward edge from its initial letter to the tail letter.
Questions converted into judgmentsa map of the directionWhether there is a rule in theEuler path。
-----------------------------------------------------
Solution
A forward graph exists Euler path.PrerequisitesIs:
the degree of each node is equal to the degree of penetration
or
There is a node s, which has a 1 less than the degree of penetration, there is a node T, the degree of 1 more than the degree of penetration
In the former case, if there is Euler path in the figure, then the starting point and end point must be the same point, and the arbitrary out of 0 nodes can be used as a starting point.
In the latter case, if the Euler path exists in the graph, then s must be the starting point, and T must be the end point.
-----------------------------------------------------
But the above conditions are only necessary, in addition to the requirements of the figure "Connectivity”,
That requires you to go all the way from the point you identified earlier (it seems like crap)
In fact, the necessary conditions in the front can only quickly determine the Euler path does not exist,
The existence of Euler paths is still going throughtraversing edges in a diagramto confirm.
------------------------------------------------------
Consider the followingHow to traverse an edge in a forward graph (possibly with a heavy edge, self-loop)。
It is not very convenient to use vector<int> g[n to save pictures, andchain-forward starIt's more convenient.
Please pay special attention to the bold three lines in the code below, and consider if you change the three lines to the following two ways
What's the problem?
void dfs (int u) { for (; ~head[u]; head[u]=e[head[u]].nt) { int &v=e[head[u]].to; DFS (v);} }
void dfs (int u) { for (; ~Head[u];) { int &v=e[head[u]].to; Head[u]=E[head[u]].nt; DFS (v);} }
----------------------------------------------------------
Code
#include <bits/stdc++.h>using namespacestd;Chars[1005];int inch[ -], out[ -];Const intM (1e5+5);structedge{intto, NT;} E[M];inthead[ -];voidDfsintu) { for(; ~Head[u];) { int v=e[head[u]].to; //This edge has been used head[u]= E[head[u]].nt; Dfs (v); }} BOOLSolveintN) { BOOLflag=true; for(intI=0; i< -; i++)if(inch[i]!= out[i]) {flag=false; Break;} if(flag) { for(intI=0; i< -; i++)if( out[i]) {DFS (i); Break;} for(intI=0; i< -; i++)if(~head[i])return 0; return 1; } ints=-1, t=-1; for(intI=0; i< -; i++){ if(inch[i]!= out[i]) { if(ABS (inch[i]- out[i])! =1)return 0; if(inch[i]> out[i]) { if(~t)return 0; T=i; } Else if(inch[i]< out[i]) { if(~s)return 0; S=i; } } } if(~s&&~t) {DFS (s); for(intI=0; i< -; i++)if(~head[i])return 0; return 1; } return 0;}intMain () {intT scanf"%d", &T); for(intN t--;) {scanf ("%d", &N); memset (inch,0,sizeof(inch)); memset ( out,0,sizeof( out)); memset (Head,-1,sizeof(head)); for(intLen, u, V, id=0, _=n; _--;) {scanf ("%s", s); Len=strlen (s); U=s[0]-'a', v=s[len-1]-'a'; out[U]++,inch[v]++; E[id]={v, Head[u]}, head[u]=id++; } puts (Solve (n)?"ordering is possible.":"The door cannot be opened."); }}
Spoj Play on Words