次小生成樹 krusal prim

2021-08-22 07:03:02 字數 2518 閱讀 7480

定義:

設g = (v, e)是連通的無向圖,t是圖g的乙個最小生成樹.如果有另外一棵樹t1,t1 ≠ t,滿足不存在樹t',t' ≠ t,w(t') < w(t1),則稱t1是圖g的次小生成樹.

演算法:1:基本演算法

最簡單也最容易想到的是,設t是g的最小生成樹,依次列舉t的邊並去掉,再求最小生成樹,所得到的這些值的最小值就是次小生成樹,由於最小生成樹有n-1條邊,這種方法就相當於執行了n次最小生成樹的演算法,演算法的時間複雜度比較高.大約是n * m的數量級.

2:演算法二

定義由最小生成樹t進行一次可行變化得到的新的生成樹所組成的集合,稱為樹t的鄰集,記為n(t).所謂可行變化即去掉t中的一條邊,再新加入g中的一條邊,使得新生成的圖仍為樹.設t是圖g的最小生成樹,如果t1滿足w(t1) = min,則t1是圖g的次小生成樹.

定理:如果圖g的點的個數v和邊的個數e個不滿足關係v = e-1,那麼存在邊(u,v) 屬於 t 和(x, y)不屬於t滿足t \ (u, v) u (x, y)是圖的一顆次小生成樹.

既然存在邊(u, v) 屬於 t 和(x, y) 不屬於t滿足t \ (u, v) u (x, y)是圖的一顆次小生成樹,那麼所有的t \ (u, v) u (x, y)剛好構成了t的鄰集,則t的鄰集中權值最小的就是次小生成樹了,但是如果每次列舉(u, v)和(x, y),還要判斷能否構成一棵樹,複雜度太高.那麼這裡應該這麼做,先加入(x,y),對於一棵樹加入(x, y)後一定會成環,如果刪去環上除(x ,y)以外權值最大的一條邊,會得到加入(x,y)時權值最小的邊.那麼接下來的問題就是如何快速求得這個環上權值最大邊了.最小生成樹中x到y的最長邊可以使用樹形動態規劃或者lca等方法在o(n2)的時間複雜度內計算出來.但是如果使用的是kruskal演算法求最小生成樹,可以在演算法的執行過程中求出x到y路徑上的最長邊,因為每次合併兩個等價類的時候,分別屬於兩個等價類的每兩個點之間的最長邊一定是當前加入的邊,按照這條性質進行記錄的話就可以求出來最小生成樹中在每兩個點的路徑上的最長邊.

演算法實現上,首先用求最小生成樹的演算法求出其權值之和為mst,然後列舉不屬於最小生成樹的邊(x, y),並新增到最小生成樹中,那麼樹必定形成環,然後刪掉這個環內(不包含(x,y))最長的邊.然後計算權值之和,列舉所有不屬於最小生成樹的邊,取其權值的最小值,就是次小生成樹.

下面用圖來說明下計算(x,y)之間的最長邊:

比如利用 kruskal 走到了上述步驟,接下來要新增邊(v2, v5),已知權值為8,那麼v2 和 v5 分別屬於兩個等價類和 的每兩個點之間的距離應該都更新為7,即length[3][2] = length[3][1] = length[3][4] = length[3][6] = 8, length[5][2] = length[5][1] = length[5][4] = length[5][6] = 7,每增加一條邊,就如此的更新下去,最後就可以得到圖中兩個節點之間的路徑上的最長距離.

下面再用圖簡單闡述下演算法:

假設上圖是圖的最小生成樹,並存在邊(v5, v6),且其權值為8,那麼當列舉到此條邊時,在圖中新增邊(v5,v6),圖中便有了乙個環,在此環中找到除新加邊以外最大的邊的權值為7,那麼刪除此邊,計算權值,然後繼續列舉其他不存在於最小生成樹的邊,從中取得最小值,就是要求的答案.

複雜度分析:整個演算法進行了一次krusal演算法,時間複雜度為o(mlogm),同時又對整個length進行賦值,時間複雜度為o(n^2),最終又進行了時間複雜度為o(m)的遍歷,總的時間複雜度是o(mlogm+n^2).

對應板題:傳送門

對應kruskal解法,附上**:

#include#include#includeusing namespace std;

const int maxn=150;

const int maxe=150*150;

const int inf=0x3f3f3f3f;

struct edge;

edge edges[maxe];

bool cmp(edge a,edge b)

pre[1]=0;

for(int i=1;ilow[j])

}sum+=min1;

vis[bj]=1;

use1[bj][pre[bj]]=use1[pre[bj]][bj]=1;

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

pre[j]=bj;}}

}}int sprim()}}

return ans;

}int main()

else}}

int u,v,w;

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

prim();

int mst=sum;

int secmst=sprim();

if(mst==secmst)else

}return 0;

}

最小生成樹 次小生成樹

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