最小生成樹(二)...Kruskal算法

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);
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章