Skip to content

Latest commit

 

History

History
85 lines (66 loc) · 3.01 KB

File metadata and controls

85 lines (66 loc) · 3.01 KB

最小生成树

地图上有 m 条无向边,每条边 (x, y, w) 表示位置 m 到位置 y 的权值为 w。从位置 0 到 位置 n 可能有多条路径。我们定义一条路径的危险值为这条路径中所有的边的最大权值。请问从位置 0 到 位置 n 所有路径中最小的危险值为多少?

最小危险值为最小生成树中 0 到 n 路径上的最大边权。以此题为例给出最小生成树的两种经典算法。

  • 算法 1: Kruskal's algorithm,使用并查集实现。
# Kruskal's algorithmclassSolution: defgetMinRiskValue(self, N, M, X, Y, W): # Kruskal's algorithm with union-findparent=list(range(N+1)) rank= [1] * (N+1) deffind(x): ifparent[parent[x]] !=parent[x]: parent[x] =find(parent[x]) returnparent[x] defunion(x, y): px, py=find(x), find(y) ifpx==py: returnFalseifrank[px] >rank[py]: parent[py] =pxelifrank[px] <rank[py]: parent[px] =pyelse: parent[px] =pyrank[py] +=1returnTrueedges=sorted(zip(W, X, Y)) forw, x, yinedges: ifunion(x, y) andfind(0) ==find(N): # early return without constructing MSTreturnw
# Prim's algorithmclassSolution: defgetMinRiskValue(self, N, M, X, Y, W): # construct graphadj=collections.defaultdict(list) foriinrange(M): adj[X[i]].append((Y[i], W[i])) adj[Y[i]].append((X[i], W[i])) # Prim's algorithm with min heapMST=collections.defaultdict(list) min_heap= [(w, 0, v) forv, winadj[0]] heapq.heapify(min_heap) whileNnotinMST: w, p, v=heapq.heappop(min_heap) ifvnotinMST: MST[p].append((v, w)) MST[v].append((p, w)) forn, winadj[v]: ifnnotinMST: heapq.heappush(min_heap, (w, v, n)) # dfs to search route from 0 to ndfs= [(0, None, float('-inf'))] whiledfs: v, p, max_w=dfs.pop() forn, winMST[v]: cur_max_w=max(max_w, w) ifn==N: returncur_max_wifn!=p: dfs.append((n, v, cur_max_w))
close