输出给定无向连通图中的欧拉回路。
输入格式:
输入首先在第一行给出图中最大顶点数量,即正整数 kMaxVertex
(≤20)。
第二行给出两个正整数,依次为当前要创建的图的顶点数 n 和边数 m(保证顶点数至少为 3 且不超过最大顶点数量)。
随后 m 行,每行给出一条无向边的两个端点的编号。顶点编号从 0 开始,编号间以 1 个空格分隔。
题目保证没有边被重复给出,并且图一定是连通的。
输出格式:
如果欧拉回路不存在,在一行中输出 No Euler circuit.
。
如果欧拉回路存在,在一行中按以下格式输出:
0->v1->v2->...->0
其中 v1
、v2
等为欧拉回路途径的顶点编号。注意回路必须从编号为 0 的顶点开始,并以回到编号为 0 的顶点结束。
输入样例 1:
20
12 21
1 3
1 4
2 3
2 8
3 4
3 6
3 7
3 9
4 5
4 7
4 10
4 11
5 10
6 9
7 9
7 10
8 9
9 0
9 10
10 11
10 0
输出样例 1:
0->10->7->9->8->2->3->4->1->3->9->6->3->7->4->5->10->11->4->10->9->0
注意:欧拉回路的输出顺序是不唯一的,以任何顺序输出都可以,有特殊裁判程序判断输出的正确性。例如下列输出也是正确的。
0->9->10->5->4->3->1->4->7->9->8->2->3->6->9->3->7->10->11->4->10->0
输入样例 2:
20
4 5
0 1
1 2
2 3
3 0
2 0
输出样例 2:
No Euler circuit.
解题思路:像拆积木一样找路径
假设图满足条件,如何找到具体路径?这里用到一个经典算法:Hierholzer算法(江湖人称“边删除法”)。
步骤拆解:
-
随便选个起点(题目要求必须是0)。
-
边走边拆桥:从当前点出发,随便选一条没走过的路,走完后把这条路“拆掉”(避免重复)。
-
如果没路可走,就把这个点加入路径,并回退到上一个点。
-
最后反转路径,得到欧拉回路。
整个过程就像搭积木再反向拆解,最终拼出一条完美路径。
代码实现(Python版)
# 读取输入:最大顶点数、实际顶点数n和边数m kMaxVertex = int(input()) n, m = map(int, input().split()) # 初始化邻接表和度数统计 adj = [[] for _ in range(n)] degrees = [0] * n for _ in range(m): u, v = map(int, input().split()) adj[u].append(v) adj[v].append(u) # 无向图,双向添加 degrees[u] += 1 degrees[v] += 1 # 检查是否所有顶点度数都是偶数 has_euler = all(d % 2 == 0 for d in degrees) if not has_euler: print("No Euler circuit.") else: # 开始Hierholzer算法 current = 0 # 题目要求起点是0 stack = [] # 辅助栈记录路径 path = [] # 最终路径 while True: if adj[current]: # 当前点还有路可走 stack.append(current) next_v = adj[current].pop() # 随便选一条路(这里取最后一条) adj[next_v].remove(current) # 拆掉双向边 current = next_v # 移动到下一个点 else: path.append(current) # 无路可走时记录该点 if not stack: # 栈空说明遍历完成 break current = stack.pop() # 回退到上一个点 # 反转路径并检查首尾是否为0 path.reverse() if len(path) < 2 or path[0] != 0 or path[-1] != 0: print("No Euler circuit.") else: print('->'.join(map(str, path)))