次小生成樹

2021-08-07 09:28:57 字數 1827 閱讀 1150

次小生成樹,由最小生成樹替換一條邊得到

在生成最小生成樹的時候,用max[i][j]來記錄從i到j的路中(這條路是唯一的)值最大的那部分,如4>1->2>3,max[4][3]記錄的是4、1和1、3和2、3中值最大的那條,為什麼要這樣記錄呢,因為求次小生成樹的時候就是列舉圖的任意兩個點:

ans = 

min(ans, min_ans + 

map[i][j] - 

max[i][j]);

ans是次小生成樹的路徑和,min_ans是最小生成樹的路徑和,map[i][j]是i,j中一條不在最小生成樹的邊(map[i][j]是要一條條列舉的),要使ans盡量小,那max[i][j]就要盡量大了,當邊替換的時候會生成乙個環,此時從最小生成樹中去掉一條邊即可,去的就是

max[i][j]。

**來自:

poj1679 the unique mst

題意:給定圖,讓求它的最小生成樹是否唯一。如果唯一的話輸出最小生成樹的權值和,否則輸出not unique!

思路:直接求次小生成樹就行。

#include

#include

#include

using

namespace

std;

const

intmaxn =

111;

const

intinf =

0x3f3f3f3f;

intmap[maxn][maxn];

//鄰接矩陣存圖

intmax[maxn][maxn];

//表示最小生成樹中i到

j的最大邊權

bool

used[maxn][maxn];

//判斷該邊是否加入最小生成樹

intpre[maxn];

intdis[maxn];

void

init(

intn)

void

read(

intm)

} intprim(

intn)

pre[

1] = 0;

dis[

1] = 0;

vis[

1] =

true;

for(

inti =

2; i <= n; i++)

} if(min_dis ==

inf)

return-1

;//如果不存在最小生成樹

ans += min_dis;

vis[k] =

true;

used

[k][

pre[k]] =

used

[pre

[k]][k] =

true;

for(

intj =

1; j <= n; j++)

} }

return

ans;

//最小生成樹的權值之和 }

intsmst(

intn,

intmin_ans)

//min_ans

是最小生成樹的權值和

void

solve(

intn)

if(smst

(n, ans) == ans)

printf

("not unique!\n");

else

printf

("%d\n"

, ans); }

intmain()

return0;

}

最小生成樹 次小生成樹

一 最小生成樹 說到生成樹首先要解釋一下樹,樹是乙個聯通的無向無環圖,多棵樹的集合則被稱為森林。因此,樹具有許多性質 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 ...