Kruskal算法——最小生成树

#include <bits/stdc++.h>
using namespace std;
int flag;
const int maxn=100000+15;
const int maxm=100000+15;
struct Edge
{
    int x,y,z;
}edge[maxm];
int n,m;
bool cmp(Edge a,Edge b)
{
    return a.z<b.z;
}
int top[maxn];
int rec[maxn];
int found(int x)
{
    if (top[x]==x) return x;
    return top[x]=found(top[x]);
}
int main()
{
    scanf("%d%d",&n,&m);
    for (int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&edge[i].x,&edge[i].y,&edge[i].z);
     } 
    sort(edge+1,edge+m+1,cmp);  //O(mlogm)
    for (int i=1;i<=n;i++) top[i]=i;
    int ans=0;
    int tot=0;
    for (int i=1;i<=m;i++)
    {
        int fx=found(edge[i].x),fy=found(edge[i].y);
        if (fx!=fy)
        {
            tot++;
            rec[i]=tot;
            ans+=edge[i].z;
            top[fx]=fy;
            if (tot==n-1) break;    
        }
    }
    cout<<ans;
    return 0;
 } 
´Kruskal算法主要分为两步:
´给所有边按照边权从小到大的顺序排序;
´从小到大依次考虑每条边(u,v)(最开始没有任何的边):
´如果u与v已经连通了,那么加入(u,v)后会出现环,不添加;
´如果u与v没有连通,那么加入(u,v)使其连通。
´然后,对于判断是否联通,我们可以通过并查集来维护。
posted @ 2017-01-25 16:24  Mr.9Pounds15Pence  阅读(157)  评论(0编辑  收藏  举报