kruskal 演算法 c++實現
阿新 • • 發佈:2018-12-18
Kruskal是另一個計算最小生成樹的演算法,其演算法原理如下。首先,將每個頂點放入其自身的資料集合中。然後,按照權值的升序來選擇邊。當選擇每條邊時,判斷定義邊的頂點是否在不同的資料集中。如果是,將此邊插入最小生成樹的集合中,同時,將集合中包含每個頂點的聯合體取出,如果不是,就移動到下一條邊。重複這個過程直到所有的邊都探查過。
struct Node //作為資料結構儲存圖
{
int start;
int end;
int length;
};
思路很簡單,程式碼實現也很簡單。以結構體陣列作為儲存結構儲存該圖的資訊,結構體由它所連線的兩個頂點和邊的權值構成。首先對邊的權值排序,這個使用封裝好的sort函式就行了,再就是選邊過程。
圖我找了一個(懶癌晚期,見笑了)。
用演算法思路描述該過程就是從小到大依次選邊,若選中的邊的兩個頂點都已經加入到樹中,則不選取該邊,只要兩個邊有一個沒有在樹中的就把這條邊加入到樹中,相應的這兩個頂點不管之前是0個或是1個已經在樹中,此時都認為這兩個頂點都已經在樹中,遍歷結束則得到最小生成樹。
#include<iostream> #include<vector> #include<algorithm> using namespace std; struct Node //作為資料結構儲存圖 { int start; int end; int length; }; bool compare(Node a, Node b) { return a.length < b.length; } void Kruskal(vector<Node> &arr, vector<bool> &visited) { int M, N; M = visited.size(); N = arr.size(); for (int i = 0; i < N; i++) { cin >> arr[i].start >> arr[i].end >> arr[i].length; } sort(arr.begin(), arr.end(), compare); int weight = 0; for (int i = 0; i < N; i++) { if (!visited[arr[i].start] || !visited[arr[i].end]) { weight += arr[i].length; visited[arr[i].start] = true; visited[arr[i].end] = true; } } cout << "最小生成樹權值為:"; cout << weight << endl; } int main() { int M,N; cin>>M>> N; vector<Node> arr(N); vector<bool> visited(M); Kruskal(arr,visited); } /* 作為測試用例送你們了 6 8 0 1 2 0 2 1 1 3 5 2 3 4 1 2 3 2 4 1 4 5 2 3 5 3 最小生成樹權值為9 */
程式碼最下面的註釋就作為測試用例送你們了,不要謝我ღ( ´・ᴗ・` )比心