📅  最后修改于: 2023-12-03 15:42:19.161000             🧑  作者: Mango
给定一个包含 n 个节点的有向图 G = (V,E),求一个大小为 k 的边集 F,使得对于 G的所有节点 u,u 到从 u 可以到达的节点 v 之间至少有 k 条边在集合 F 中。
4 4 2
1 2
2 3
3 1
3 4
1 3
2 1
这道题等价于给所有节点分别连一条长为k的链,最后把所有链合成一张图。如果原来的有向图是强连通的,那么合并得到的图也是强连通的,满足题目要求。如果有向图不强连通,那么合并后的图中至少有一个点是没法到达其他点的,无解。
import queue
# 构建有向图
n, m, k = map(int, input().split())
graph = [[] for _ in range(n + 1)]
indegree = [0] * (n + 1)
for i in range(m):
u, v = map(int, input().split())
graph[u].append(v)
indegree[v] += 1
# 拓扑排序求出起始点集合
start_nodes = []
q = queue.Queue()
for i in range(1, n + 1):
if indegree[i] == 0:
start_nodes.append(i)
q.put(i)
# 对于每个起始点,往后跳k步的链是否存在
f = []
for s in start_nodes:
L = set([s])
for _ in range(k):
new_L = set()
for u in L:
for v in graph[u]:
new_L.add(v)
L = new_L
if len(L) < n:
print("-1")
exit(0)
for u in L:
f.append((s, u))
# 输出结果
for u, v in f:
print(u, v)
代码解释:
时间复杂度:$\mathcal{O}(mn+n^2)$
空间复杂度:$\mathcal{O}(n + m + k)$