資料結構與演算法之最好學的最小生成樹

2022-08-25 10:30:32 字數 2042 閱讀 1356

數缺形時少直觀,形缺數時難入微。

——華羅庚

最小生成樹問題是我在各項圖論問題中最先理解與解決的,其目的就是在連通圖中選擇出:

使得各點構成聯通的最小邊權的邊集

其中用到的資料結構與演算法也是相對很好理解的並查集kruskal演算法,我在我之前的文章小話資料結構-圖 (聚焦與於實現的理解)

也有提到過,現在再來系統的闡述一下這問題的解決思路。

並查集是一種樹型的資料結構,用於處理一些不相交集合的合併及查詢問題

並查集是乙個寫法簡單,經常使用到的資料結構,主要操作有以下三種

初始化操作

int p[n]; //

儲存每個點的祖宗節點

for (int i = 1; i <= n; i ++)

p[i] = i;//

初始化,節點編號是1~n

查詢函式

int find( int

x )

合併操作

p[find(a)] = find(b);//

將a加入b的祖宗的集合

並查集還可以維護每乙個子集的大小、或是自子集到祖宗節點的距離,給出以下**,只是使用kruskal演算法只需要使用樸素的並查集就可以了。

int p[n], size[n];//

p儲存每個點的祖宗節點, size表示祖宗節點所在集合中的點的數量

int find(intx)​

for (int i = 1; i <= n; i ++ )

//合併a和b所在的兩個集合並儲存集合中元素個數:

size[find(b)] +=size[find(a)];

p[find(a)] = find(b);

int p[n], d[n];//

p儲存每個點的祖宗節點, d[x]儲存x到p[x]的距離

int find(int

x)

return

p[x];

}​

for (int i = 1; i <= n; i ++ )

//合併a和b所在的兩個集合:

p[find(a)] =find(b);

d[find(a)] = distance; //

初始化find(a)的偏移量

這個頂著乙個高階名字的針對解決最小生成樹的演算法,也就是乙個徹頭徹尾的貪心思想的演算法,基本的步驟如下

①:將所有邊按照權值從小到大排序

②:將所有邊依次放入圖中,如果沒有連入新的點,則丟棄不要。

③:當整個圖聯通時,返回結果

這裡給一張別人部落格裡非常直觀的**

在②步驟中,並查集就可以發揮出其作用,快速的判定出當前選擇的邊的點是否在乙個集合中,從而方便的實現演算法。

那我們直接用**來實現:

int

n, m;

intp[n];

​struct

edgeedges[m];

​int find(intx)​

intkruskal()

}​

if (cnt < n - 1) return inf;//

若結束後不能使整個圖聯通,則無法求出結果

return

res;

}

至此,kruskal演算法就成功實現了,可以根據實際情況改變部分引數,從而獲得需要求解的部分。

資料結構與演算法之最好學的最小生成樹

最小生成樹問題是我在各項圖論問題中最先理解與解決的,其目的就是在連通圖中選擇出 使得各點構成聯通的最小邊權的邊集 其中用到的資料結構與演算法也是相對很好理解的並查集和kruskal演算法,我在我之前的文章小話資料結構 圖 聚焦與於實現的理解 也有提到過,現在再來系統的闡述一下這問題的解決思路。並查集...

資料結構與演算法之最好學的最小生成樹

int p n 儲存每個點的祖宗節點 for int i 1 i n i p i i 初始化,節點編號是1 n 查詢函式 int find int x 合併操作 p find a find b 將a加入b的祖宗的集合 並查集還可以維護每乙個子集的大小 或是自子集到祖宗節點的距離,給出以下 只是使用k...

資料結構之最小生成樹

最小生成樹 乙個連通圖的生成樹是乙個極小連通子圖,它含有圖中全部頂點,但只有足以構成一棵樹的n 1條邊。這種構造連通網的最小代價生成樹稱為最小生成樹,詳見資料結構之圖 術語 儲存結構 遍歷 求連通網的最小生成樹有兩種經典方法 普里姆 prime 演算法和克魯斯卡爾 kruskal 演算法。假設n v...