📅  最后修改于: 2023-12-03 15:28:37.973000             🧑  作者: Mango
本文将介绍GATE CS 2018考试中的第39章,该章节主要涵盖了:
Tarjan算法是求解有向图强连通分量的常用算法之一。它的时间复杂度为O(m+n),其中m为有向图中的边数,n为顶点数。
算法步骤:
示例代码:
def TarjanSCC(graph):
n = len(graph)
ID = [0] * n
low = [0] * n
onstack = [False] * n
stack = []
time = 0
SCCs = []
def dfs(u):
nonlocal time
ID[u] = low[u] = time
time += 1
stack.append(u)
onstack[u] = True
for v in graph[u]:
if ID[v] == 0:
dfs(v)
low[u] = min(low[u], low[v])
elif onstack[v]:
low[u] = min(low[u], ID[v])
if ID[u] == low[u]:
scc = []
while True:
v = stack.pop()
onstack[v] = False
scc.append(v)
if v == u:
break
SCCs.append(scc)
for u in range(n):
if ID[u] == 0:
dfs(u)
return SCCs
最小生成树算法是求解图的最优子结构的一个经典问题。它的具体含义为,给定一个无向图,求其生成树中总边权最小的那棵树。
Prim算法是一种贪心算法,其思路为从一个顶点开始,每次添加到生成树集合中的边权最小的那条边,直到所有顶点都被添加到生成树中为止。
算法步骤:
示例代码:
import heapq
def prim(graph, s=0):
n = len(graph)
marked = [False] * n
mst = []
pq = []
def visit(u):
marked[u] = True
for v, w in graph[u]:
if not marked[v]:
heapq.heappush(pq, (w, u, v))
visit(s)
while pq:
w, u, v = heapq.heappop(pq)
if not marked[v]:
marked[v] = True
mst.append((u, v, w))
visit(v)
return mst
Kruskal算法也是一种贪心算法,其思路为在图中找到边权最小的边,将其加入生成树中,并判断是否形成了环,如果没有形成环,则将该边加入当前生成树中。
算法步骤:
示例代码:
def kruskal(graph):
n = len(graph)
mst = []
uf = UnionFind(n)
edges = sorted((w, u, v) for u, e in graph.items() for v, w in e)
for w, u, v in edges:
if uf.find(u) != uf.find(v):
uf.union(u, v)
mst.append((u, v, w))
return mst
以上就是GATE CS 2018考试中第39章的内容介绍。涵盖了有向图的强连通分量和两种最小生成树算法(Prim算法和Kruskal算法)。对于算法学习和应用都有很大的参考价值。