Kruskalアルゴリズムシミュレーションの説明
3960 ワード
Kruskalアルゴリズムは最小生成ツリーを求めるアルゴリズムであり,すなわち最小のオーバーヘッドを求めるなどである.
アルゴリズムは、最小生成ツリーを要求すると、n個のノードはn−1個のエッジしか含まない
だから私たちはこの最も短いn-1辺を探すことに変換すべきで、そのため、まずすべての
小さいものから大きいものまで並べ替えながら、1本ずつ取り出して試してみて、リングになるかどうか見てみましょう.
リングを構成しなければ、最短の経路に違いない.毎回最小をとるからだ.
のエッジを探して、最終的に最小の生成ツリーの代価とを求めることができます.
テスト例:
結果:
アルゴリズムは、最小生成ツリーを要求すると、n個のノードはn−1個のエッジしか含まない
だから私たちはこの最も短いn-1辺を探すことに変換すべきで、そのため、まずすべての
小さいものから大きいものまで並べ替えながら、1本ずつ取り出して試してみて、リングになるかどうか見てみましょう.
リングを構成しなければ、最短の経路に違いない.毎回最小をとるからだ.
のエッジを探して、最終的に最小の生成ツリーの代価とを求めることができます.
/*
Filename:kruskal.cpp
Author: xiaobing
E-mail: [email protected]
Date: 2013-08-31
*/
#include<iostream>
#include<string>
#include<string.h>
#include<algorithm>
#include<cstdlib>
#include<list>
#include<set>
#include<vector>
#define N 100
#define INF 1000000
using namespace std;
/*
Kruskal ,
, , n n-1
n-1 , ,
, , ,
, ,
, 。
:
struct edge ,
edge graph[N] N
int father[N]
: , ,
, ,
, ,
, , father[N], , -1,
( ),
, ,
, x > y father[x] = y, ,
, -1, , ,
, , ,
。
*/
//
struct edge{
int u; //
int v; //
int cost; //
};
//
bool cmp(const edge &a, const edge &b){
return a.cost < b.cost;
}
//
int findFather(int father[], int x){
// -1, ,
if(father[x] != -1){
//
return father[x] = findFather(father, father[x]);
}
// -1,
return x;
}
//
bool unionEdge(int father[], int x, int y){
//
x = findFather(father, x);
y = findFather(father, y);
// , ,
// , , fasle
if(x == y){
return false;
}
// ,
if(x > y) father[x] = y;
if(x < y) father[y] = x;
// , true
return true;
}
int main(){
edge graph[N]; // N
int father[N]; // N
int i,j, n; //n
cin>>n;
//
memset(graph, 0, sizeof(graph));
// -1 ,
memset(father, -1, sizeof(father));
int k = 0, cost, temp;
//
for(i = 0;i < n;i++)
for(j = 0;j < n;j++){
if(i > j){
graph[k].u = i;
graph[k].v = j;
cin>>cost;
// 0 , , INF
if(cost < 0){
graph[k].cost = INF;
} else {
graph[k].cost = cost;
}
k++;
continue;
}
// , ,
cin>>temp;
}
//
sort(graph, graph + k, cmp);
//
for(i = 0;i < k;i++){
cout<<i<<" "<<graph[i].u<<"->"<<graph[i].v<<": "<<graph[i].cost<<endl;
}
//count , n-1
//sum
int count = 0, sum = 0;
// k
for(i = 0; i < k;i++){
//
if(unionEdge(father, graph[i].u, graph[i].v)){
count++;
sum += graph[i].cost;
}
// n-1 , ,
if(count == n - 1) break;
}
cout<<" sum : "<<sum<<endl;
return 0;
}
テスト例:
7
0 5 -1 -1 -1 11 2
5 0 10 8 -1 -1 13
-1 10 0 7 -1 -1 -1
-1 8 7 0 12 9 4
-1 -1 -1 12 0 10 -1
11 -1 -1 9 10 0 3
2 13 -1 4 -1 3 0
結果:
0 6->0: 2
1 6->5: 3
2 6->3: 4
3 1->0: 5
4 3->2: 7
5 3->1: 8
6 5->3: 9
7 2->1: 10
8 5->4: 10
9 5->0: 11
10 4->3: 12
11 6->1: 13
12 2->0: 1000000
13 6->4: 1000000
14 6->2: 1000000
15 3->0: 1000000
16 5->2: 1000000
17 5->1: 1000000
18 4->2: 1000000
19 4->1: 1000000
20 4->0: 1000000
sum : 31