最小生成树

Posted huaruoji

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了最小生成树相关的知识,希望对你有一定的参考价值。

最小生成树

最小生成树就是在一个图中寻找一个联通图,必须包含原图的所有节点,且这个图的所有边的权值和最小.
为什么是一个树呢?因为只要求联通,就一定没有环,没有环不就是树了嘛!

Kruskal算法

Kruskal算法的核心是加边和判环.一条一条把边加上,如果加上会形成环就不加,最后弄成一个连通图.

假设有n个节点,就需要加(n-1)条边.为什么呢?因为每加上一条边,就会多连接一个点.
因为是要求最小生成树,所以先将所有边权值从小到大排序,挨个加边,加完的值一定是最小的.
判环主要用并查集实现,若两个节点的祖先不同,则加边后不会形成环,反之会形成环.

P3366 【模板】最小生成树

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>

using namespace std;
int n,m,p,sum,father[5005];
struct Edge
{
    int x,y,w;
}a[200005];
int getfather(int);
void merge(int,int);
bool cmp(const Edge &a,const Edge &b);

int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++) father[i]=i;
    for(int i=1;i<=m;i++)
    { 
        cin>>a[i].x>>a[i].y>>a[i].w;
    }
    sort(a+1,a+m+1,cmp);
    int k=0;
    for(int i=1;i<=m;i++)
    {
        if(getfather(a[i].x)!=getfather(a[i].y))
        {
            ++k;
            merge(a[i].x,a[i].y);
            sum+=a[i].w;
        }
        if(k==n-1) break;
    }
    cout<<sum;
    
    return 0;
}

int getfather(int v)
{
    if(father[v]!=v) father[v]=getfather(father[v]);
    return father[v];
} 

void merge(int a,int b)
{
    father[getfather(a)]=getfather(b);
}

bool cmp(const Edge &a,const Edge &b)
{
    return a.w<b.w; 
}

Prim算法

核心:加点
(未完待续)

以上是关于最小生成树的主要内容,如果未能解决你的问题,请参考以下文章

最小生成树matlab代码Kruskal算法,用于二维网络生成

c语言最小生成树

最小生成树及Prim算法及Kruskal算法的代码实现

数据结构 图连通与最小生成树

次最小生成树 模版

图的最小生成树算法(图解+代码)| 学不会来看我系列