首页 > 其他 > 详细

最小生成树

时间:2017-05-16 22:18:28      阅读:265      评论:0      收藏:0      [点我收藏+]

Kruskal算法

 Kruskal算法是基于贪心的思想得到的。首先我们把所有的边按照权值先从小到大排列,接着按照顺序选取每条边,如果这条边的两个端点不属于同一集合,那么就将它们合并,直到所有的点都属于同一个集合为止。

http://cogs.pro/cogs/problem/problem.php?pid=7

/****************************************************************************************************

                                        最小生成树(Kruskal) 
                        

********************************************************************************************************/
#include<cstdio>
#include<algorithm>
using namespace std;
struct Edge{
    int from,to,dist;
    bool operator <(const Edge a)const{
        return dist<a.dist;
    }
}a[1200000];
int mFind[1550];
int Find(int x){//并查集 
    if(mFind[x]==x)return x;
    else mFind[x]=Find(mFind[x]);
    return mFind[x];
}
int main(){
    freopen("mcst.in","r",stdin);
    freopen("mcst.out","w",stdout);
    int n,x,a1=0;scanf("%d",&n);
    for(int i=0;i<n;i++){
        for(int j=0;j<n;j++){
            scanf("%d",&x);
            if(x!=-1&&i<j)a[a1].from=i,a[a1].to=j,a[a1++].dist=x;
        }
    }
    for(int i=0;i<n;i++)mFind[i]=i;
    sort(a,a+a1);int j=0; //将所有边排序 
    int fa,fb,u,v,ans=0;
    for(int i=1;i<n;i++){//将连接两部分的最短边加入生成树 
        while(1){
            u=a[j].from,v=a[j].to;
            fa=Find(u),fb=Find(v);
            if(fa!=fb){
                ans+=a[j++].dist,mFind[fa]=fb;
                break;
            }
            j++;
        }
    }
    printf("%d",ans);
    return 0;
}

 

最小生成树

原文:http://www.cnblogs.com/bennettz/p/6863767.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!