最小生成树

关于最小生成树,实际上就俩算法,kruskal 和 prim 要说的话《信息学奥赛一本通c++提高篇》 上面都有讲

事实上我也就只会 kruskal

关于这两个算法,kruskal是加边,prim是加点,实际只要会一种算法大部分问题就A了

Kruskal

在边排序好后不断加边就好了,比较容易理解,因为最大生成树就要求树上最小的边最大

这时就可以用结构体存边

struct node{
    int u; int v; int w;
}a[100005];
bool cmp(node x,node y){return x.w <y.w ;}//最小生成树

 

要判断两点是否已经联通,用并查集

int fa[305],n,m,ans=0,tot=1;
int find(int x)
{
    if(fa[x]==x) return x;
    else return fa[x]=find(fa[x]);
}

然后就是kruskal

void kruskal()
{
    for(int i=1;i<=n;i++)
    fa[i]=i;//并查集初始化
    sort(a+1,a+m+1,cmp);//边初始化
    for(int i=1;i<=m;i++)
    {
        if(find(a[i].u )==find(a[i].v )) continue;//两点已联通,过
        fa[find(a[i].u )]=find(a[i].v );//联通两点
        ans=max(ans,a[i].w );//这里要看题目要求,这里要求输出最长边
        tot++;//边数加
        if(tot==n) break;//一棵树的边==节点数-1,由于tot开始赋1,so...
    } 
    return ;
}

 

 

posted @ 2019-12-06 21:06  小霜降  阅读(107)  评论(0编辑  收藏  举报