python欧拉回路

输出给定无向连通图中的欧拉回路。

输入格式:

输入首先在第一行给出图中最大顶点数量,即正整数 kMaxVertex(≤20)。
第二行给出两个正整数,依次为当前要创建的图的顶点数 n 和边数 m(保证顶点数至少为 3 且不超过最大顶点数量)。
随后 m 行,每行给出一条无向边的两个端点的编号。顶点编号从 0 开始,编号间以 1 个空格分隔。
题目保证没有边被重复给出,并且图一定是连通的。

输出格式:

如果欧拉回路不存在,在一行中输出 No Euler circuit.
如果欧拉回路存在,在一行中按以下格式输出:

0->v1->v2->...->0

其中 v1v2 等为欧拉回路途径的顶点编号。注意回路必须从编号为 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算法(江湖人称“边删除法”)。

步骤拆解:

  1. 随便选个起点(题目要求必须是0)。

  2. 边走边拆桥:从当前点出发,随便选一条没走过的路,走完后把这条路“拆掉”(避免重复)。

  3. 如果没路可走,就把这个点加入路径,并回退到上一个点。

  4. 最后反转路径,得到欧拉回路。

整个过程就像搭积木再反向拆解,最终拼出一条完美路径。


代码实现(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)))

欧拉回路的本质是“平衡”——每个路口的进出次数必须相等。而Hierholzer算法通过“拆边+回溯”巧妙地解决了路径构造问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值