題目1249:次小生成樹
時間限制:1 秒
記憶體限制:32 兆
特殊判題:否
提交:140
解決:37
題目描述:最小生成樹大家都已經很了解,次小生成樹就是圖中構成的樹的權值和第二小的樹,此值也可能等於最小生成樹的權值和,你的任務就是設計乙個演算法計算圖的最小生成樹。
輸入:存在多組資料,第一行乙個正整數t,表示有t組資料。
每組資料第一行有兩個整數n和m(2<=n<=100),之後m行,每行三個正整數s,e,w,表示s到e的雙向路的權值為w。
輸出:輸出次小生成樹的值,如果不存在輸出-1。
樣例輸入:
23 31 2 1
2 3 2
3 1 3
4 41 2 2
2 3 2
3 4 2
4 1 2
樣例輸出:
46
比起次小生成樹模板題,就多了個判斷是否存在次小生成樹。
判斷是否存在最小生成樹,分兩種情況
第一種,最小生成樹不存在,那次小生成樹顯然不存在。
第二種,最小生成存在,但不存在次小生成樹,那肯定是所有的邊剛好形成最小生成樹,沒有邊剩餘。
關於求最小生成樹的演算法,我這裡用了兩次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 ...