最小生成樹總結

2021-07-14 23:59:22 字數 1793 閱讀 5659



啊,先紀念一下吧,難得一天這麼

666 ac

完了所有題 (次小生成樹**看懂)

今天學到了最小生成樹演算法中的

prim

演算法和kruskal

演算法。從巨集觀上來講

prim

更適合稠密圖,

krustal

更適合稀疏圖,但對於我們來說暫時沒有什麼區別啦。

prim

演算法中主要注意的點是

在visit陣列與minn陣列(最小到達某點的權邊的權值)上 注意只有未遍歷而且小於當前所存的權才可以更新

迴圈次數為n-1次,錯誤的次數會導致答案錯誤

除自身為0以外,所有點之間的初始距離為正無窮

kruskal

演算法中主要注意的點是

所有的邊要用結構體存,方便快排

注意並查集的getfather函式的壓縮路徑和union函式的是否父親相同的判斷

注意變數k的維護,k滿足k==n-1時必須及時跳出迴圈

還有乙個很容易忽略的問題!!就是memset,特別是有多組資料的時候必須在前面重置記憶體

附上我對次小生成樹**的注釋:

#include #include #include #include using namespace std;

/* * 次小生成樹

* 求最小生成樹時,用陣列max[i][j]來表示mst中i到j最大邊權

* 求完後,直接列舉所有不在mst中的邊,替換掉最大邊權的邊,更新答案

* 點的編號從0開始

*/const int maxn=110;

const int inf=0x3f3f3f3f;//最大值

bool vis[maxn];//點是否已使用

int lowc[maxn];//到每乙個點權值最短的路徑的權值

int pre[maxn];//存父親

int max[maxn][maxn];//max[i][j]表示在最小生成樹中從i到j的路徑中的最大邊權

bool used[maxn][maxn];//邊是否已使用

int prim(int cost[maxn],int n)

if(minc==inf) return -1;//該圖不是連通圖

ans+=minc;//權值和計算

vis[p]=true;//點已遍歷

used[p][pre[p]]=used[pre[p]][p]=true;//邊已遍歷

for(int j=0;jcost[p][j])}}

return ans;

}int ans;

int smst(int cost[maxn],int n)

int cost[maxn][maxn];

int main()

while(m--)

ans=prim(cost,n);

if(ans==-1)

if(ans==smst(cost,n)) printf("not unique!\n");//權值和完全相同

else printf("%d\n",ans);//輸出最小生成樹的權值和

}return 0;

}



最小生成樹總結

給定一張圖,圖中有許多的節點還有許多長度不同的邊將這些點點相互連線,找出連線所有點的最短方式就是最小生成樹,可以證明,這樣一種最小的情況是不會出現環的,由於所有的無環圖都可以看做樹,所以成為最小生成樹。頂層思想是分治,選擇策略是貪心,實現方法如下 以邊為中心,先將所有的邊從小到大進行排序,之後依照大...

最小生成樹總結

研究了一天最小生成樹 衍生出來包括最小瓶頸樹,次小生成樹,最小樹形圖之類的演算法,前兩者基本能搞定,最後那個就。不太懂了日後再回去看吧似乎很少用到,抄個模板以備不時之需 先談談最小瓶頸樹 首先注意這兩個定理 命題 無向圖的最小生成樹一定是瓶頸生成樹。命題 瓶頸生成樹不一定是最小生成樹 好了 知道這個...

最小生成樹總結

最小生成樹的性質 1 最小生成樹並不唯一,準確的來說是最小生成樹的樹形並不唯一 2 最小生成樹的權值之和唯一,並且是最小的 3 最小生成樹的邊數 頂點數 1 求最小生成樹有兩種經典演算法 普里姆演算法 prim 和克魯斯卡爾 kruskal 演算法 演算法比較 時間複雜度比較 prim在稠密圖中比k...