Hiho Euler's road 2, hiho Euler's Road
Hiho Euler's road 2
Analysis:
Ho: Let me know this simple puzzle!
Hi, really?
<10 minutes later>
Ho: Ah, ah! You can't fix it !!! The number of dominoes is too large.
Hi, I know you have problems.
Ho: Hi, come and help me!
Hi, OK. Let's solve this problem together.
<Xiao Hi Thought About It>
Hi: It turns out to be like this... Let's take a closer look at this example:
Because the two numbers are always the same, we can write them only once. In this example, we can write them as follows: 3-2-4-3-5-1. The six numbers have exactly five gaps, and the numbers on both sides of each gap correspond to exactly one card.
If we think of every number as a point, each card is regarded as an edge. What do you think?
Small Ho: In this example, it is:
We need to connect all the dominoes, that is, to take all the edges once. Sorry, isn't that a problem with Euler's path!
Hi, that's right. This is actually an issue of the Euler's path, but it's different from the last one. This time we need to find an Euler's path.
Ho: how can we find a path?
Hi little: Let's borrow the previous example.
Using our last method to prove Euler's path determination, we found two paths in this example:
L1: 4-5-2-3-6-5L2: 2-4-1-2
Suppose we stack S to record the node sequence for every path search. When we find L1, the situation in stack S is:
S: 4 5 2 3 6 5 [Top]
At this point, we step out the stack and delete these edges. When we reach Node 2, we find that node 2 is a common node of L1 and L2. In addition, L2 can return to node 2 after passing through other edges. If we leave L2 first in this place and continue to go L1, we will just walk through all the sides.
In the previous proof, we know that, except for L1, other paths L2 and L3. must all satisfy the same point as the start point and end point. Therefore, from any public node, there must be a path to return to this node.
Therefore, we obtain an algorithm:
Here is an example with three layers:
In this example:
L1: 1-2-6-5-1L2: 2-3-7-2L3: 3-4-8-3
In the first step, we press L1 into Stack S, and we use an array Path to record the order of the stack:
S: [1 2 6 5 1]Path:
Then, when we exit the stack to node 2, we find another path in node 2, so we add another path in step 2:
S: 1 [2 3 7 2]Path: 1 5 6
At this time, L2 has been completed, and then the element pops up until we find that 3 has other paths, also pushed into the stack:
S: 1 2 [3 4 8 3]Path: 1 5 6 2 7
Then, the remaining elements are displayed in sequence:
S: Path: 1 5 6 2 7 3 8 4 3 2 1
The Path is exactly the Euler's Path we need.
Small Ho: It's really clever to find Euler's path in this way.
Little Hi: And this algorithm also has a clever way to implement it. DFS itself is a process of inbound and outbound stack, So we directly use the nature of DFS to implement the stack. Its pseudocode is as follows:
DFS (u): While (u has an undeleted edge e (u, v) to delete the edge e (u, v) DFS (v) endPathSize exceeds PathSize + 1 Path [PathSize] ← u
# Include <iostream> # include <cstdio> # include <cstring> # include <string. h >#include <algorithm> # include <vector> using namespace std; const int N = 1005; int n, m, flag, top, sum, du [N], ans [5005], map [N] [N]; void dfs (int x) {ans [++ top] = x; for (int I = 1; I <= n; I ++) {if (map [x] [I]> = 1) {map [x] [I] --; map [I] [x] --; dfs (I); break ;}} void fleury (int x) {top = 1; ans [top] = x; while (top> 0) {int k = 0; (Int I = 1; I <= n; I ++) // determines whether it can be expanded {if (map [ans [top] [I]> = 1) // if an edge exists from ans [top], it can be expanded to {k = 1; break;} if (k = 0) // If point x does not have any other side, you can leave it first (that is, it cannot be expanded). Then output it {printf ("% d", ans [top]); top --;} else if (k = 1) // which route can be extended by dfs {top --; // pay attention to dfs (ans [top + 1]) ;}} int main () {while (scanf ("% d", & n, & m )! = EOF) {memset (du, 0, sizeof (du); memset (map, 0, sizeof (map); for (int I = 1; I <= m; I ++) {int x, y; scanf ("% d", & x, & y); map [x] [y] ++; // record the edge. Because it is an undirected graph, two edges are added. There may be multiple edges between the two points. map [y] [x] ++; du [x] ++; du [y] ++;} flag = 1; // flag indicates the start point. If all vertices are even, search sum = 0 from 1; for (int I = 1; I <= n; I ++) {if (du [I] % 2 = 1) {sum ++; flag = I; // if an odd edge exists, search from odd edge} if (sum = 0 | sum = 2) fleury (flag);} return 0 ;}