次小生成樹

2022-04-30 11:51:17 字數 2795 閱讀 8749

首先求出最小生成樹,我們列舉每條不在最小生成樹上的邊,並把這條邊放到最小生成樹上面,然後就一定會形成環,那麼我們在這條環路中取出一條最長的路(除了新加入的那一條邊)。最終我們得到的權值就是次小生成樹的權值。

prim演算法實現:

我們在求解次小生成樹的時候我們要使用乙個二維陣列maxd[i][j]表示最小生成樹中i點到j點的最遠距離,我們使用動態規劃的思想來計算這個陣列,比如當前節點為x,他的父親節點為per[x],以及根節點root,那麼 maxd[root][x] = max(maxd[root][per[x]] , maxd[per[x]][x]);

kruskal演算法實現:

kruskla演算法中我們列舉的邊權值會依次增大,那麼就會給我們計算提供一定的便利,但是因為kruskal的實現方式和prim有所不同,所以kruskal需要儲存當前最小生成樹中的節點,然後我們再去更新maxd陣列。

prim:

1 #include 2 #include 3 #include 4 #include 5

#define inf 0x3f3f3f3f67

using

namespace

std;

8const

int maxn = 110;9

int10

bool

vis[maxn],connect[maxn][maxn];

11int

dis[maxn],maxd[maxn][maxn],per[maxn];

12void

init()

1317

intprim()

1825 vis[1] = 1

;26 dis[1] = 0;27

int res = 0;28

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

2936

if(index == -1) return

res;

37 vis[index] = 1

;38 connect[index][per[index]] = false;connect[per[index]][index] = false;//

這條邊已經在最小生成樹中,後面我們就不能新增這條邊了

39 res +=temp;

40 maxd[per[index]][index] =maxd[index][per[index]] =  temp;//

更新點之間的最大值

41for(int j = 1;j <= n;j ++)

4247

4852}53

}54return

res;55}

56int

main()

5771

int ans =prim();

72bool over = false;73

//如果有某條邊沒有被最小生成樹使用,並且i~j的最大值大於圖中得到最大值,那麼就表示次小生成樹存在

74//

相反就不會存在

75for(int i = 1;!over && i <= n;i ++)

76for(int j = 1;j <= n;j ++)

7785}86

if(over)

87 printf("

not unique!\n");

88else

89 printf("

%d\n

",ans);90}

91//

如果我們需要求解次小生成樹的權值時,我們就要把在最小生成樹中沒有用過的邊,加上然後減去對應環中最大的路徑

92return0;

93 }

kruskal:

1 #include 2 #include 3 #include 4 #include 5 #include 6

#define inf 0x3f3f3f3f78

using

namespace

std;

9int

n,m;

10struct

data

11 p[20010

];15 vectorg[110

];16

int per[110],maxd[110][110

];17

bool

cmp(data a,data b)

1821

int union_find(int

x)22

25void

kruskal()

2634

int sum=0,k=0;//

sum是最小生成樹的值

35for(int i=0; i)

3660}61

int cisum=inf;//

次小生成樹的權值

62for(int i=0; i)

63if(!p[i].vis)

64 cisum=min(cisum,sum+p[i].w-maxd[p[i].u][p[i].v]);

65if(cisum>sum)

66 printf("

%d\n

",sum);

67else

68 printf("

not unique!\n");

69}70int

main()

7182

kruskal();83}

84return0;

85 }

最小生成樹 次小生成樹

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