最小生成樹之kruskal算法

前言:

  先介紹一下最小生成樹。對於n個結點,用n-1條邊使它們相聯通,形成一棵樹,這個樹就叫生成樹,其中所有邊權值和最小的生成樹就是最小生成樹。

其次,介紹一下kruskal算法的思想。1.講所有邊按升序排序,2,選擇權值最小的邊。如果邊的兩個結點不在一個連通分量裏,就把一個結點的根節點作爲另一個結點的根節點的子節點;反之,在同一個連通分量中,忽略掉。3.重複第二步直到所有頂點都在一個連通分量中。

這裏,連通分量的判定和結點之間的合併用到了並查集。

問題:

還是暢通工程。

某省調查鄉村交通狀況,得到的統計表中列出了任意兩村莊間的距離。省政府“暢通工程”的目標是使全省任何兩個村莊間都可以實現公路交通(但不一定有直接的公路相連,只要能間接通過公路可達即可),並要求鋪設的公路總長度爲最小。請計算最小的公路總長度。 

Input

測試輸入包含若干測試用例。每個測試用例的第1行給出村莊數目N ( < 100 );隨後的N(N-1)/2行對應村莊間的距離,每行給出一對正整數,分別是兩個村莊的編號,以及此兩村莊間的距離。爲簡單起見,村莊從1到N編號。 
當N爲0時,輸入結束,該用例不被處理。 

Output

對每個測試用例,在1行裏輸出最小的公路總長度。 

Sample Input

3
1 2 1
1 3 2
2 3 4
4
1 2 1
1 3 4
1 4 1
2 3 3
2 4 2
3 4 5
0

Sample Output

3
5

代碼:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<string>

using namespace std;
const int maxn=100;
int n,sum;
int root[maxn];

struct Edge{
    int l,r,cost;
    bool operator < (const Edge &A) const{//ÖØÔØÔËËã·û£¬±ãÓÚÅÅÐò¡£
        return cost<A.cost;
    }
};

int findRoot(int x)
{
    while(x!=root[x])
    {
        root[x]=root[root[x]];
        x=root[x];
    }
    return x;
}

int unionRoot(Edge e)
{
    int xx=findRoot(e.l);
    int yy=findRoot(e.r);
    if(xx!=yy)
    {
        root[yy]=xx;
        sum+=e.cost;
    }

}

int main()
{
    while(cin>>n&&n!=0)
    {
        Edge edge[5000];
        for(int i=0;i<n*(n-1)/2;i++)
            cin>>edge[i].l>>edge[i].r>>edge[i].cost;
        sort(edge,edge+n*(n-1)/2);
      
        sum=0;
        for(int i=1;i<=n;i++)
            root[i]=i;
        for(int i=0;i<n*(n-1)/2;i++)
           unionRoot(edge[i]);

        cout<<sum<<endl;
    }
    return 0;
}

結果:

總結:

時間複雜度:

O(eloge)

e:總邊數。

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