巧用二分图匹配:Python实现有向无环图最小路径覆盖问题求解
为了解决有向无环图(DAG)的最小路径覆盖问题,可以使用二分图匹配的方法。具体思路是将DAG的每个顶点拆分成两个顶点,分别放入二分图的左右两部分,然后通过寻找二分图的最大匹配,利用最小路径覆盖数等于顶点数减去最大匹配数的性质来求解。 下面是使用Python实现的代码: ```python from collections import defaultdict # 匈牙利算法求二分图最大匹配 def find_path(u, vis, match, graph): for v in graph[u]: if v not in vis: vis.add(v) if v not in match or find_path(match[v], vis, match, graph): match[v] = u return True return False # 计算最大匹配数 def max_match(graph, n): match = {} res = 0 for i in range(1, n + 1): vis = set() if find_path(i, vis, match, graph): res += 1 return res # 构建路径 def build_paths(match, n): paths = [] used = [False] * (n + 1) for i in range(1, n + 1): if not used[i]: path = [] cur = i while True: used[cur] = True path.append(cur) found = False for v in match: if match[v] == cur: cur = v found = True break if not found: break paths.append(path) return paths # 主函数 n, m = map(int, input().split()) graph = defaultdict(list) for _ in range(m): u, v = map(int, input().split()) graph[u].append(v) # 计算最大匹配数 max_matching = max_match(graph, n) # 计算最小路径覆盖数 min_path_cover = n - max_matching # 构建路径 paths = build_paths({v: u for u, v in match.items()}, n) # 输出路径 for path in paths: print(" ".join(map(str, path))) # 输出最少路径数 print(min_path_cover) ``` 代码解释 1. 匈牙利算法求二分图最大匹配:`find_path` 函数用于寻找增广路径,`max_match` 函数通过不断调用 `find_path` 函数来计算二分图的最大匹配数。 2. 构建路径:`build_paths` 函数根据匹配结果构建路径,从每个未使用的顶点开始,沿着匹配边遍历,直到无法继续。 3. 主函数:读取输入,构建图,计算最大匹配数和最小路径覆盖数,构建路径并输出。 复杂度分析 - 时间复杂度:匈牙利算法的时间复杂度为 $O(nm)$,其中 $n$ 是顶点数,$m$ 是边数。 - 空间复杂度:主要用于存储图和匹配信息,空间复杂度为 $O(n + m)$。 ######[AI问答 | 714点数解答 | 2025-12-12 18:51:59]
- Python 运行报错:urllib3 网络连接创建失败,原因及排查建议(字节豆包 | 161点数解答 | 2024-10-31 00:39:36)458
- Python 实现球类:精准计算半径、表面积与体积,附输入验证与异常处理!(阿里通义 | 261点数解答 | 2024-11-28 21:19:39)343
- Windows环境下C/C++项目开发:完整目录、文件路径及编译脚本设置示例(字节豆包 | 459点数解答 | 2024-11-02 20:38:01)234
- Python正则表达式:精准匹配字符串“abcablc”中的第二个“a”(字节豆包 | 554点数解答 | 2025-06-12 15:25:28)120
- Python 实战:学生信息列表转字典、遍历、深拷贝及数据修改全流程(GPT | 422点数解答 | 2024-10-29 15:43:54)414
- Python实战:学生成绩列表转字典,深拷贝与数据修改操作全解析(字节豆包 | 254点数解答 | 2024-10-29 16:01:39)405
- 旅行售货员问题:详细步骤剖析与贪心算法Python代码实现(字节豆包 | 444点数解答 | 2024-12-17 03:32:59)275
- Dev C++ 实现旅行售货员问题:最小路程路线代码与详细解析 (字节豆包 | 448点数解答 | 2024-12-17 03:33:42)176
- C++ 求解 P1020 小核桃与删除字符串问题:双指针与枚举策略 (字节豆包 | 330点数解答 | 2026-02-07 18:40:10)23
- 51 单片机:定时器 0 实现 8 个 LED 循环点亮,附代码及优化建议(字节豆包 | 1193点数解答 | 2024-12-27 15:10:29)310
- Java调用Python接口中文乱码?设置UTF - 8编码一招解决!(讯飞星火 | 263点数解答 | 2024-06-06 17:07:59)389
- 解决Java调用Python接口中文乱码问题:设置UTF - 8编码全攻略(讯飞星火 | 160点数解答 | 2024-06-06 17:18:39)414