[模板]最小生成树 kruskal算法

模板题目

题目描述

如题,给出一个无向图,求出最小生成树

输入输出格式

输入格式:
第一行包含两个整数N、M,表示该图共有N个结点和M条无向边。(N<=5000,M<=200000)

接下来M行每行包含三个整数Xi、Yi、Zi,表示有一条长度为Zi的无向边连接结点Xi、Yi

输出格式:
输出包含一个数,即最小生成树的各边的长度之和

输入输出样例

输入样例#1:
4 5
1 2 2
1 3 2
1 4 3
2 3 4
3 4 3
输出样例#1:
7
说明

时空限制:1000ms,128M

数据规模:

对于20%的数据:N<=5,M<=20

对于40%的数据:N<=50,M<=2500

对于70%的数据:N<=500,M<=10000

对于100%的数据:N<=5000,M<=200000
样例解释

所以最小生成树的总边权为2+2+3=7

分析

这道题目呢,在入门的时候讲过prim算法。这里对于prim算法进行简单的介绍。prim算法,就是把所有的点划在A集合里面,然后每次选择一个点到B集合(满足AB结点的交叉边保持最小)然后边数达到n-1的时候就成功了。
克鲁斯卡尔
克鲁斯卡尔就是基于并查集的。把每个点都看成一个集合,然后对每条边进行按权值从小到大排序,如果当前边的两个端点不在一个集合里面(查),那就,并他;在一个集合里面就,不要他。(哈哈哈还是我讲的贪心算法的应用)

代码

#include<bits/stdc++.h>
using namespace std;
int n,m,cc=0,sum=0;
struct edge
{
    int l,r,v;
}a[200200];
//用来存放所有的边,l和r是两个端点,v是权值
int top;
int father[6000];
//用来存放所有结点的父亲
void read()
{
    scanf("%d%d",&n,&m);
    int x,y,z;
    for(int i=1;i<=m;i++)
    {
        scanf("%d%d%d",&x,&y,&z);
        a[i].l=x;
        a[i].r=y;
        a[i].v=z;
    }
    for(int i=1;i<=n;i++)
    father[i]=i;
}
//读入和初始化
bool mycmp(edge x,edge y)
{
    return x.v<y.v;
}
int getfather(int v)
{
    if(father[v]==v) return v;
    father[v]=getfather(father[v]);
    return father[v];
}
//获取根结点
void un(int x,int y)
{
    int fx,fy;
    fx=getfather(x);
    fy=getfather(y);
    father[fx]=fy;
}
//并集
bool judge(int x,int y)
{
    int fx,fy;
    fx=getfather(x);
    fy=getfather(y);
    return fx!=fy;
}
//查点
void work()
{
    for(int i=1;i<=m&&cc<=n-1;i++)
    //cc存储已经拥有的边数。最多n-1条
    if(judge(a[i].l,a[i].r))
    //如果没有在一个结点里面。
    {
        un(a[i].l,a[i].r);
        //并
        cc++;
        //计数
        sum+=a[i].v;
        //累加权值和
    }
}
int main()
{
    read();
    sort(a+1,a+1+m,mycmp);
    //按权值排序
    work();
    printf("%d",sum);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值