演算法 最小生成樹的關鍵邊和偽關鍵邊

2022-07-03 10:36:07 字數 1449 閱讀 5665

給你乙個 n 個點的帶權無向連通圖,節點編號為 0 到 n-1 ,同時還有乙個陣列 edges ,其中 edges[i] = [fromi, toi, weighti] 表示在 fromi 和 toi 節點之間有一條帶權無向邊。最小生成樹 (mst) 是給定圖中邊的乙個子集,它連線了所有節點且沒有環,而且這些邊的權值和最小。

請你找到給定圖中最小生成樹的所有關鍵邊和偽關鍵邊。如果從圖中刪去某條邊,會導致最小生成樹的權值和增加,那麼我們就說它是一條關鍵邊。偽關鍵邊則是可能會出現在某些最小生成樹中但不會出現在所有最小生成樹中的邊。

請注意,你可以分別以任意順序返回關鍵邊的下標和偽關鍵邊的下標。

新增鏈結描述

解題思路:

為什麼在判斷偽關鍵邊的時候,需要排除關鍵邊呢?

因為我們是通過求樹上分別提前加上每一條邊時,最小生成樹的權重是否會發生變化的依據,來判斷偽關鍵邊的,而關鍵邊當然也包含了這個性質,但是偽關鍵邊不包含第二步的性質,所以,先判斷得出關鍵邊,然後再第三步判斷時剔除關鍵邊。

圖中去掉關鍵邊和樹中新增非關鍵邊對最小生成樹權重的影響,如下圖所示。

// 定義邊

class edge

}class solution

// 將所有邊新增到列表當中

listnes = new arraylist<>();

for(int i = 0; i < edges.length; i++)

// 第一步,計算最小生成樹的權重

int mintreeweight = mintreeweightcal(new arraylist<>(p), nes, 0);

// 初始化答案列表

list> res = new arraylist<>();

res.add(new arraylist<>());

res.add(new arraylist<>());

// 複製乙個臨時邊集,用於刪邊操作

listtempedges = new arraylist<>(nes);

// 第二步,先列舉所有邊,檢視這條邊是不是關鍵邊

for(edge e : nes)

// 將刪去邊放回去

tempedges.add(e);

}// 第三步,再判斷每條邊是不是偽關鍵邊

for(edge e : nes)

}return res;

}// kruskal演算法求最小生成樹,引數分別表示點的並查集,邊列表,初始權重

private int mintreeweightcal(listp, listnes, int w)

}return w;

}// 並查集模板方法,求當前元素所在集合的根元素

private int find(listp, int x)

return p.get(x);}}

最小生成樹演算法

由帶權的連通圖生成的數的各邊加起來稱為生成樹的權,把權值最小的生成樹稱為最小生成樹 minimum spanning tree 簡稱為mst 構造最小生成樹的方法就是利用mst性質,一條一條地選擇可以加入的邊。下面介紹兩種用於構造最小生成樹的演算法,其中第一種演算法稱為prim演算法,第二種演算法稱...

最小生成樹演算法

乙個最簡單的最小生成樹 圖結構練習 最小生成樹 time limit 1000ms memory limit 65536k 有n個城市,其中有些城市之間可以修建公路,修建不同的公路費用是不同的。現在我們想知道,最少花多少錢修公路可以將所有的城市連在一起,使在任意一城市出發,可以到達其他任意的城市。輸...

演算法 最小生成樹

前言 最小生成樹是在乙個給定的無向圖中求一棵樹,這棵樹包含無向圖中的所有頂點,且樹中的邊都來自無向圖中的邊,並且要滿足整棵樹的邊權之和最小。1 最小生成樹是樹,其邊數等於頂點數減1,且不會有環 2 對於給定的圖最小生成樹可以不唯一,但是邊權之和一定是唯一的。3 其根節點可以是這棵樹上的任何乙個節點,...