對於乙個圖來說,我們可以選擇不同的邊而產生不同的樹,由於邊的選擇不一樣,每一條邊的權值不一樣,那我們最後生成出來的樹的權值也就不一樣,kruskal演算法和prim演算法就是來找怎樣選擇邊才可以使產生的樹的權值最小。
kruskal演算法思路:現在有乙個集合q,來表示圖中的所有的點,有乙個集合u,來表示已經生成樹中的點,當我們選擇了一條邊,那我們就將這條邊的兩個頂點加入到u中,初始時有n個點,m條邊。
既然我們要求的是生成的樹的權值最小,那麼我們是不是可以依次選擇圖中的最小邊呢?由於一共用n個點,m條邊,那麼我們要選的邊的最小的個數就是n-1。按照這樣的思路,那我們首先要做的就是將這m條邊進行從小到大排序,我們只要依次選擇這些排好序的邊就可以了,當我們已經將某個點已經加入到了我們生成樹中,我們就不選擇這條邊。那麼問題就來了,怎樣來判斷某個點是否已經加入到生成樹中?這個時候我們可以使用並查集來判斷這個點是否已經加入到了生成樹中。 關於並查集:
**實現:
#include#include可以看出kruskal演算法選擇邊,而下面要說是如何通過選擇點來實現最小生成樹。using
namespace
std;
int father[1000000
];struct
node
;int find(int root)//
並查集查詢函式
int merge(int a,int b)//
並查集合並函式
return
0;//
不能夠合併返回0
}bool cmp(node a,node b)//
排序 int
main()
if(cnt==n-1)//
生成樹中有n-1個點時,選擇完成 。
break
; }
cout
/輸出最小生成樹的權值。
return0;
}
prim演算法思路:要使用prim演算法,首先我們要介紹兩個陣列,dis[ ]陣列和book[ ]陣列,dis[ i ]的作用是記錄第 i 個點與當前生成的樹的最小距離,如果有些點與當前的生成樹沒有直連邊,那麼我們就將他的值設為無窮大。我們每一次選擇的點都是距離當前生成樹距離最小的點。
book[ i ]只有兩個值1和0,當book[ i ]=1時,表示 i 這個點已經被選了,book[ i ]=0時表示 i 這個點還沒有被選。由於我們不斷在選擇點加入到樹中,那麼現在的問題就是如何來更新dis[ i ]陣列。
dis陣列模擬演示:
首先我們任選乙個點作為初始點,在這個選擇v1。此時相當於生成樹中只有乙個點。可以看到與v1直接相連的有v2,v3,v4。按照上面的講述,那麼初始化dis陣列的為:dis=(inf代表無窮大)。
此時我們選擇了v1,那麼book[ 1 ]=1。
步驟:
1:在dis[ ]陣列找到最小值(已經選過的點不考慮)所對應的點(即下標)。
2:將該點加入到生成樹中。在這裡可以到此時加入的點是v3,那麼book [ 3 ]=1。
3:找到v3的直連邊,v2,v4,v5,v6。那麼我們就要更新dis[ ]陣列下標所對應的值。
可以看到v1—>v3—>v2=6與v1—>v2=6相等,那麼就不更新dis[ 2 ]。
v1—>v3—>v4=6大於v1—>v4=5,那麼不跟新dis[ 4 ]。
v1—>v3—>v5=7小於inf,更新dis[ 5 ]=7。
v1—>v3—>v6=5小於inf,更新dis [ 6 ]=5。
4:重複1—3步驟,直到所有的點都被加入到了生成樹中,此時的樹就是最小生成樹。
**實現:
#includeusingnamespace
std;
#define inf 99999;
int book[10000
];int e[10000][10000];//
存圖:
int dis[100000
];int
main()
} for(int i=0;i)
for(int i=0;i<=n;i++)
book[i]=0;//
初始化book陣列
for(int i=1;i<=n;i++)//
選擇第乙個點來初始化dis陣列
dis[i]=e[1
][i];
book[
1]=1
;
for(int i=0;i<=n-2;i++)
}book[u]=1;//
標記選中的點
sum+=dis[u];//
生成樹的權值加上此時被選中的權值
for(int k=1;k<=n;k++)//
更新dis陣列
}cout
<
return0;
}
最小生成樹演算法
由帶權的連通圖生成的數的各邊加起來稱為生成樹的權,把權值最小的生成樹稱為最小生成樹 minimum spanning tree 簡稱為mst 構造最小生成樹的方法就是利用mst性質,一條一條地選擇可以加入的邊。下面介紹兩種用於構造最小生成樹的演算法,其中第一種演算法稱為prim演算法,第二種演算法稱...
最小生成樹演算法
乙個最簡單的最小生成樹 圖結構練習 最小生成樹 time limit 1000ms memory limit 65536k 有n個城市,其中有些城市之間可以修建公路,修建不同的公路費用是不同的。現在我們想知道,最少花多少錢修公路可以將所有的城市連在一起,使在任意一城市出發,可以到達其他任意的城市。輸...
演算法 最小生成樹
前言 最小生成樹是在乙個給定的無向圖中求一棵樹,這棵樹包含無向圖中的所有頂點,且樹中的邊都來自無向圖中的邊,並且要滿足整棵樹的邊權之和最小。1 最小生成樹是樹,其邊數等於頂點數減1,且不會有環 2 對於給定的圖最小生成樹可以不唯一,但是邊權之和一定是唯一的。3 其根節點可以是這棵樹上的任何乙個節點,...