luoguP3366 模板最小生成树 x

Posted 云深不知处

tags:

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

 P3366 【模板】最小生成树

    • 2.4K通过
    • 6.3K提交
  • 题目提供者HansBug
  • 标签 云端↑ 生成树
  • 难度 普及-
  • 时空限制 1s / 128MB

题目描述

如题,给出一个无向图,求出最小生成树,如果该图不连通,则输出orz

输入输出格式

输入格式:

 

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

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

 

输出格式:

 

输出包含一个数,即最小生成树的各边的长度之和;如果该图不连通则输出orz

 

输入输出样例

输入样例#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

思路:

  首先这道题是求最小生成树的模板,求最小生成树的办法有2种:

    1)prim

    2)kruskal

坑点:

  记住要判断什么时候输出“orz”

上代码:

1)prim

  在网页上找了不少题解后,突然发现,还是kruskal比较好理解。。。

  写prim的有各式各样的2333

  在这里就不贴出代码啦~感兴趣的话,可以手动请教一下度娘2333

2)kruskal

#include <algorithm>
#include <iostream>
#include <cstdio>
using namespace std;

const int N = 5010;
const int M = 200020;
int n,m,ans;
int dad[N];

struct A {
    int u,v,w;
    bool operator < (const A &qwq)const
    {
        return w < qwq.w;
    }
}t[M];

int getdad(int x)
{ return dad[x] == x ? x : dad[x] = getdad( dad[x] ); }

void kruskal()
{
    sort(t+1,t+1+m);
    for(int i=1;i<=m;i++)
    {
        int f1=getdad(t[i].u),f2=getdad(t[i].v);
        if(f1!=f2)
        {
            dad[f1]=f2;
            ans+=t[i].w;
        }
    }
    int tmp=getdad(1);
    for(int i=2;i<=n;i++)
    {
        if(getdad(i)!=tmp)
        {
            printf("orz");
            return;
        }
    }
    printf("%d\n",ans);
}

int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++)
        scanf("%d%d%d",&t[i].u,&t[i].v,&t[i].w);
    for(int i=1;i<=n;i++)
        dad[i]=i;
    kruskal();
    return 0;
}

 

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

P3366 模板最小生成树 (贪心+并查集,kruskal)

P3366 模板最小生成树 (贪心+并查集,kruskal)

3366 模板最小生成树(Kruskal)

最小生成树模板题-----P3366 模板最小生成树

洛谷 P3366 模板最小生成树

洛谷P3366 模板最小生成树