最小生成樹

2021-09-22 07:44:09 字數 1775 閱讀 3317

最小生成樹定義:包含所有頂點和n-1條邊且邊權值和最小的樹

次小生成樹定義:由最小生成樹換一條邊可得到的樹

次小生成樹證明:

最小生成樹

做法原理:切分定理——給定任意切分,橫切邊中權值最小的邊必然屬於最小生成樹

kruskal演算法

運用並查集,刷題參考

prime演算法

參考 只刷了krusal的題後續補

一.kruskal

1.poj2421 模版題

2.uva1395 找最大權值與最小權值差別最小的樹,關鍵是想明白使程式更高效,越早生成完的樹差別最小,那麼就只要改變起點就可以了。

在一張圖中,有n個點,每個點與別的點有邊相連,如此就形成了乙個圖,現在要找一棵樹經過所有的點(即有n個點,n-1條邊),權值最小的那個樹就是最小生成樹。

因為橫切邊中權值最小的邊必定屬於最小生成樹,所以我們只要只要找到這n-1條權值最小邊就可以構建出乙個最小生成樹。

而橫切邊是什麼呢,邊是對於點而言,如果不加,這2個點不連通,加上這2個點連通,那麼這個就是橫切邊,否則就不是橫切邊

基於此,我們就去找這n-1個橫切邊,有2種找法,

一種是prime,從點找起,因為經過每個點,最小橫切邊對於最初始的那個邊來說是它所連的權值最小的那個邊,

找當前外接邊中最小的邊,用最小堆,判斷這個邊可行否,如果由這個邊到達的這個點沒有被訪問過那麼這個邊可行,然後

加入由這個新的點衍生出的外接邊入最小堆。

一種是kruscal,從邊入手,既然是橫切邊中權值最小的邊必定屬於最小生成樹,我們就把所有邊都按權值排序,

最小的那個邊一定是,加入,接著看第2小的邊是不是橫切邊,橫切邊的條件是沒有這個邊,那麼邊的2邊

是不連通的,可以用並查集來查詢,最後是就加入,以此類推判斷第3,4,5,…小的邊。

由此,可以看出kruscal由於並查集的高效,是首選的方法,但是如果是稠密圖,點多邊少的情況,prime更加適用。

poj2485是個板子題

//kruscal寫法

#include#includeusing namespace std;

const int maxn=125999;

struct re

bool operator < (const re &a)const

for(int i=1;i<=n;i++)fa[i]=i;

sort(road+1,road+th+1);

int cnt=1,i;

for( i=1;i<=th;i++)

printf("%d\n",road[i].val);

}return 0;

}

//prime寫法

#include#include#include#include#includeusing namespace std;

const int maxn=125999;

struct re

bool operator<(const re &a)const

};vectordian[maxn];

priority_queuenow;

int vi[maxn];

int main(void)

for(int i=0;ivi[1]=1;

int cnt=n-1;

int ans=-1;

while(1)

if(cnt==0)break;

}printf("%d\n",ans);

}return 0;

}

最小生成樹 次小生成樹

一 最小生成樹 說到生成樹首先要解釋一下樹,樹是乙個聯通的無向無環圖,多棵樹的集合則被稱為森林。因此,樹具有許多性質 1.兩點之間的路徑是唯一的。2.邊數等於點數減一。3.連線任意兩點都會生成乙個環。對於乙個無向聯通圖g的子圖,如果它包含g的所有點,則它被稱為g的生成樹,而各邊權和最小的生成樹則被稱...

最小生成樹

package 圖 最小生成樹是用最少的邊吧把所有的節點連線起來。於是和圖的深度優先搜素差不多。class stack public void push int key public int pop 檢視棧頂的元素 public int peek public boolean isempty cla...

最小生成樹

define max vertex num 20 最大頂點數 typedef int adjmatrix max vertex num max vertex num 鄰接矩陣型別 typedef char vertextype typedef struct mgraph struct dnodecl...