次小生成樹

2021-09-19 18:58:26 字數 1913 閱讀 5057

判斷最小生成樹是否唯一,求次小生成樹。

原理首先求得最小生樹,然後列舉沒有在最小生成樹上的邊,加上這個邊之後樹上必定成環,刪除環上除剛加入邊的最長邊,就得到乙個新的生成樹。

實現演算法的關鍵是記錄兩點在最小生成樹上的最大距離

// kruskal

int n, m;

struct ac

}g[maxn*maxn]

;vector<

int> son[maxn]

;int pre[maxn]

, dis[maxn]

[maxn]

;int find (

int x)

void

kruskal()

sort

(g, g+m)

;int sum =0;

int cnt =0;

for(

int i =

0; i < m;

++i)

// 更新兩點的距離最大值

for(

int j =

0; j < lenx;

++j)

} pre[fy]

= fx;

//合併子樹

for(

int j =

0; j < leny;

++j)

son[fy]

.clear()

;}int ans = inf;

for(

int i =

0; i < m;

++i)

printf

("%d %d\n"

, sum, ans)

;}

// prim

int n, m;

int g[maxn]

[maxn]

, val[maxn]

, vis[maxn]

, dis[maxn]

;int pre[maxn]

, maxd[maxn]

[maxn]

;bool used[maxn]

[maxn]

;void

prim

(int s)

vis[s]=1

;int sum =

0, cnt =0;

for(

int i =

1; i < n;

++i)}if

(u ==-1

)break

; vis[u]=1

; sum +

= min;

cnt++

; used[pre[u]

][u]

= used[u]

[pre[u]]=

1;maxd[u]

[pre[u]

]= maxd[pre[u]

][u]

= min;

for(

int j =

1; j <= n;

++j)

if(vis[j]==0

&& dis[j]

> g[u]

[j])}}

if(cnt != n-1)

int ans = inf;

for(

int i =

1; i <= n;

++i)

}printf

("%d %d\n"

, sum, ans)

;}

板子題

poj 1679

accode

hdu 4081

accode

uva 10600

accode

uva 10462

accode

最小生成樹 次小生成樹

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

次小生成樹

演算法引入 設g v,e,w 是連通的無向圖,t是圖g的一棵最小生成樹 如果有另一棵樹t1,滿足不存在樹t t t1 則稱t1是圖g的次小生成樹 演算法思想 鄰集的概念 由t進行一次可行交換得到的新的生成樹所組成的集合,稱為樹t的鄰集,記為n t 設t是圖g的最小生成樹,如果t1滿足 t1 min,...

次小生成樹

分類 圖論 2013 02 12 15 03 32人閱讀收藏 舉報次小生成樹 在求最小生成樹時,用陣列path i j 來表示mst中i到j最大邊權。求完後,直接列舉所有不在mst中的邊,把它加入到mst中構成一棵新的樹,且該樹有環,此環是由剛加入的邊 i,j 造成的,所以可以通過刪除path i ...