Kruskal算法
簡單說明一下該算法
該算法就是不斷向一個集合裏不斷加最短邊,然後通過並查集判斷是否可以加入此最短邊。
typedef struct{
int x,y,len;
} Edge //這個結構體定義了一條邊,其中x,y代表這個邊的兩個頂點,len代表這條邊的長度
//當將所有邊都記錄在這樣結構的數組中後,對這個數組進行按邊的大小排序。
sort(Edge)
//假設有n個頂點,所以需要加入n-1條邊,然後從邊集合裏依次判斷能否加入,直到加入了n-1條邊
#include<iostream>
#include<algorithm>
using namespace std;
#define MAX 200 // denote the maximun number of the vertexs
struct Edge{
int x,y,len,flag;
};
Edge E[MAX*MAX/2];
int len=0,ans=0,d[MAX],g[MAX][MAX];
bool cmp(Edge,Edge);
int Find(int x,int *a);
void Union(int x,int y,int *a);
bool isNconnected(int x,int y,int *a);
int main(){
int n;
while(cin>>n){
for(int i=0;i<n;++i)
for(int j=0;j<n;++j)
cin>>g[i][j];
for(int i=0;i<n;++i)
for(int j=0;j<i;++j){
E[len].x = i,E[len].y = j,E[len].len = g[i][j];
len++;
}
sort(E,E+len,cmp);
for(int i=0;i<n;++i)d[i] = i;
for(int j=0,i=0;j<n-1&&i<len;++i){
if(isNconnected(E[i].x,E[i].y,d)){
Union(E[i].x,E[i].y,d);
ans+=E[i].len , ++j;
}
}
cout<<ans<<endl;
}
return 0;
}
bool cmp(Edge x,Edge y){
return x.len<y.len;
}
int Find(int x,int *a){
if(a[x] == x)return x;
return a[x] = Find(a[x],a);
}
void Union(int x,int y,int *a){
int i = Find(x,a), j = Find(y,a);
a[i] = j;
}
bool isNconnected(int x,int y,int *a){
return Find(x,a) != Find(y,a);
}