1. 程式人生 > >kruskal 演算法 c++實現

kruskal 演算法 c++實現

        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
*/

 程式碼最下面的註釋就作為測試用例送你們了,不要謝我ღ( ´・ᴗ・` )比心