題目1249 次小生成樹

2021-06-26 19:29:44 字數 1441 閱讀 6234

題目1249:次小生成樹

時間限制:1 秒

記憶體限制:32 兆

特殊判題:否

提交:140

解決:37

題目描述:最小生成樹大家都已經很了解,次小生成樹就是圖中構成的樹的權值和第二小的樹,此值也可能等於最小生成樹的權值和,你的任務就是設計乙個演算法計算圖的最小生成樹。

輸入:存在多組資料,第一行乙個正整數t,表示有t組資料。

每組資料第一行有兩個整數n和m(2<=n<=100),之後m行,每行三個正整數s,e,w,表示s到e的雙向路的權值為w。

輸出:輸出次小生成樹的值,如果不存在輸出-1。

樣例輸入:

2

3 31 2 1

2 3 2

3 1 3

4 41 2 2

2 3 2

3 4 2

4 1 2

樣例輸出:

4

6

比起次小生成樹模板題,就多了個判斷是否存在次小生成樹。
判斷是否存在最小生成樹,分兩種情況
第一種,最小生成樹不存在,那次小生成樹顯然不存在。
第二種,最小生成存在,但不存在次小生成樹,那肯定是所有的邊剛好形成最小生成樹,沒有邊剩餘。
關於求最小生成樹的演算法,我這裡用了兩次kruskal演算法,怎麼說呢,第一次用kruskal演算法(第一次複雜度是o(elog(e)))是求最小生成樹,並記錄下最小生成樹的邊的序號。容易知道,次小生成樹是在最小生成樹的基礎上替換一條邊形成的,所以我們列舉最小生成樹的每條邊,刪除它,並再用kruskal演算法(以後複雜度都是o(n),因為前面已經排序過了,就不用再排序了)算出剔除這條邊的最小生成樹,即剔除這條邊所能產生最小的次小生成樹,最後都列舉一遍就可以算出最終的次小生成樹,我表達不太好,看**吧。
#include#include#include#include#includeusing namespace std;

const int l=100005,inf=1<<30,maxn=1005;

struct nodeedge[l];

int fa[maxn],n,m,id[maxn],idpos;

void init();

int find(int x);

void unite(int x,int y);

bool cmp(node a,node b);

bool same(int x,int y);

int kruskal();

int secondtree(int pos)

{ init();

// sort(edge,edge+m,cmp);

int sum=0,cnt=0;

for(int i=0;i

最小生成樹 次小生成樹

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