導航:首頁 > 源碼編譯 > 求最小生成樹演算法代碼及運行圖片

求最小生成樹演算法代碼及運行圖片

發布時間:2025-01-12 07:17:49

① 用破圈法求最小生成樹

感覺上你那裡的「演算法基本思想」實現難度很大,因為圖的連通性不好維護
找圈的話,隨便找個節點為根DFS整個圖,然後在這樣的DFS生成樹中,每條非樹邊都對應了一個圈,每次找一條非樹邊,刪去所在圈中最長邊生成一個新樹,直到不存在非樹邊為止,剩下的就是最小生成樹了
具體實現的時候,先求出一個DFS生成樹,然後遞歸處理每棵子樹

假設要處理的子樹根節點為u,對該子樹破圈法的粗略偽代碼如下:

void 破圈法(u)
{
for ( v是u的每個子節點 ) 破圈法(v);
for ( e是連接u與其後繼的每條非樹邊 )
{
v=e的另一個端點;
e'=u到v之間的最長樹邊;
if (w[e]>=w[e']) 刪除邊e;//w[e]表示e的權
else
{
//用w表示原先e'的在樹中較深的端點,p[v]表示v的親節點
刪除邊e';
if (v!=w)
{
將v列入u的子節點列表;
將p[v]、p[p[v]]、...、w這條路徑反向,並將p[v]列入v的子節點列表;
}
}
}
}

上述過程不加優化的時間復雜度為O(VE),效率非常差
貌似其中找最長邊和將v的若干祖先節點路徑反向的兩步優化空間比較大,或許可將整個時間復雜度下降到O(ElgV),研究中

② c加加提問,克魯斯卡爾演算法是什麼

克魯斯卡爾演算法,從邊的角度求網的最小生成樹,時間復雜度為O(eloge)。和普里姆演算法恰恰相反,更適合於求邊稀疏的網的最小生成樹。

對於任意一個連通網的最小生成樹來說,在要求總的權值最小的情況下,最直接的想法就是將連通網中的所有邊按照權值大小進行升序排序,從小到大依次選擇。

由於最小生成樹本身是一棵生成樹,所以需要時刻滿足以下兩點:

③ 最小生成樹演算法描述

最小生成樹演算法的求解過程通常從一個空樹開始,逐步添加邊以形成一棵包含n-1條邊的最小生成樹。這個通用演算法可以用偽代碼簡潔表示:



最小生成樹的求解步驟如下:



這可以用Pascal、Prim演算法或Kruskal演算法等具體實現,它們的區別在於尋找安全邊的方式不同:





(3)求最小生成樹演算法代碼及運行圖片擴展閱讀

一個有 n 個結點的連通圖的生成樹是原圖的極小連通子圖,且包含原圖中的所有 n 個結點,並且有保持圖聯通的最少的邊。

④ 求最小生成樹的kruska演算法,效率盡量高,盡量多點注釋!c++代碼

/*
基本演算法思想:
為使生成樹上總的權值之和達到最小,則應使每一條邊上的權值盡可能地小,自然應從權值最小的邊選起,直至選出 n-1 條互不構成迴路的權值最小邊為止。
具體作法如下:首先構造一個只含 n 個頂點的森林,然後依權值從小到大從連通網中選擇不使森林中產生迴路的邊加入到森林中去,直至該森林變成一棵樹為止,這棵樹便是連通網的最小生成樹。
由於生成樹上不允許有迴路,因此並非每一條居當前權值最小的邊都可選。

用並查積 和 克魯是卡爾演算法實現查找最短邊
利用快排按邊遞增排列,每次從中選出最短邊,同時將最短邊的兩個頂點並入到集合中
心得:利用並查積 和 kruskal演算法結合找最短路徑可以使查找的效率更高
加入集合中的邊都是構成最小生成樹的邊,所以每家一次sum 都要加上這兩個頂點之間的距離
*/
/*下面的代碼輸入n個節點,然後輸入n*(n-1)/2條邊及權值,輸出是連通這些邊的最小權值*/
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;

struct ed
{
int u; //起始點
int v; //終結點
int w; //權重
};
bool cmp(ed a,ed b)
{
return a.w<b.w; //從小到大排序
}
struct ed edge[100000];
int p[105];

int find(int x) //查找x的父親
{
while(p[x]!=x)
x=p[x];
return x;
}
int kruskal(int n)
{
int i,count=1,sum=0;
for(i=0;i<=n;i++)
p[i]=i; //並查集初始化,每個節點到父親是自己
int x,y;
sort(edge,edge+n*(n-1)/2,cmp); //快速排序
for(i=0;count<n;i++)
{
x=find(edge[i].u); //點edge[i].u的父親是x
y=find(edge[i].v); //點edge[i].v的父親是y
if(x!=y) //判斷是否會路
{
count++; //加上一條邊
p[x]=y; //把x和y加入統一個集合
sum+=edge[i].w;
}
}
return sum;
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF&&n) //輸入n個節點
{
int i;
for(i=0;i<n*(n-1)/2;i++) //輸入 n*(n-1)/2條邊
scanf("%d%d%d",&edge[i].u,&edge[i].v,&edge[i].w); //表示點edge[i].u和點edge[i].v之間的權重為 edge[i].w
printf("%d\n",kruskal(n));
}
return 0;
}

樓主,這可是本人一個字一個字敲出來點,要給分啊

閱讀全文

與求最小生成樹演算法代碼及運行圖片相關的資料

熱點內容
不知道密碼怎麼強制解壓 瀏覽:179
疫情就是命令防控就是 瀏覽:870
linux查看存儲設備 瀏覽:243
stc1t單片機 瀏覽:313
英華特渦旋壓縮機 瀏覽:4
編解碼器的輸入輸出干擾 瀏覽:542
往復式壓縮氣缸過熱的原因 瀏覽:839
4u伺服器機箱怎麼賣 瀏覽:461
如何自學葡萄牙語app 瀏覽:456
擺來擺去的游戲解壓 瀏覽:270
centos注銷命令 瀏覽:859
vue多端編譯 瀏覽:755
程序員qq表白代碼編輯 瀏覽:893
聯想伺服器怎麼進後台 瀏覽:116
安卓定製rom怎麼刷 瀏覽:540
三層交換機的配置命令 瀏覽:112
49演算法公式 瀏覽:792
求最小生成樹演算法代碼及運行圖片 瀏覽:932
python掃雷計數 瀏覽:881
什麼安卓手機品牌最保值 瀏覽:847