luoguP3366 模板最小生成树 x
Posted 云深不知处
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了luoguP3366 模板最小生成树 x相关的知识,希望对你有一定的参考价值。
-
- 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)