P3366 模板最小生成树
题目描述
如题,给出一个无向图,求出最小生成树,如果该图不连通,则输出orz。
输入格式
第一行包含两个整数N,M,表示该图共有N个结点和M条无向边。
接下来M行每行包含三个整数 Xi,Yi,Zi,表示有一条长度为Zi的无向边连接结点Xi,Yi。
输出格式
如果该图连通,则输出一个整数表示最小生成树的各边的长度之和。如果该图不连通则输出orz。

数据规模
1≤N≤5000,1≤M≤200000.
这道题是最小生成树的模板题。求最小生成树有两种算法,分别为Prim算法和Kruskal算法。在这两种算法中,Prim算法更适合于稠密图最小生成树的求解(边数远大于点数),而Kruskal算法则更适用于稀疏图的最小生成树求解(边数和点数相差不大)。最小生成树的实质就是求解一种将整张图连接起来且边权最小的问题,这里只介绍Kruskal算法,它相对于Prim算法的应用更为广泛一些。
Kruskal算法前置知识:并查集(这篇博客讲得非常清楚)。
这里直接介绍Kruskal算法的内容。
首先,Kruskal算法的成立建立在一个定理上:在一张图中,边权最小的边一定在这张图的最小生成树上。
这样我们就可以进行Kruskal算法的步骤了。
首先,我们对读入的每条边按照边权的大小从小到大进行排序。这里读入边时我们不需要开一个邻接矩阵,开一个结构体,定义三个变量来分别记录每一条边的x,y,z即可。
接下来,我们需要维护一个并查集fa[ ],来记录这张图中的两个顶点间是否已经联通。同时,我们需要维护好并查集的两个基本操作:查(find)和并(unionn)。
然后,我们在主函数中需要枚举边,依次判断该边的两个顶点间是否已经联通,如果未联通,则将这条边加入最小生成树,同时将边权和sum加上该边的边权。
这里有一个优化:不需要枚举图中的所有边。我们记录一个变量cnt,记录一共有多少条边已被加入最小生成树。当加入的边数等于点数减一时,就可以停止循环。同时,如果我们枚举到最后一条边cnt都没有达到边数减一,说明该图本身就不连通,则建立最小生成树失败。
以上就是Kruskal算法求最小生成树的基本过程。最后奉上模板题的AC代码:
1 #include<iostream>
2 #include<algorithm>
3 using namespace std;
4 int n,m;
5 struct bian{//开结构体来存储边
6 int start;
7 int end;
8 int val;
9 }a[200005];
10 int fa[200005];//并查集
11 bool cmp(bian a,bian b){//将边按照边权从小到大进行排序
12 return a.val<b.val;
13 }
14 int find(int x){//并查集基本操作:查询节点x的祖宗
15 if(x==fa[x]){
16 return x;
17 }else{
18 return fa[x]=find(fa[x]);//路径压缩
19 }
20 }
21 void unionn(int x,int y){//并查集基本操作:合并
22 int r1=find(x);
23 int r2=find(y);
24 fa[r1]=r2;
25 }
26 int main(){
27 cin>>n>>m;
28 for(int i=1;i<=m;i++){
29 cin>>a[i].start>>a[i].end>>a[i].val;
30 }
31 sort(a+1,a+m+1,cmp);//按照边权从小到大进行排序
32 for(int i=1;i<=n;i++){//并查集初始化
33 fa[i]=i;
34 }
35 int cnt=0;//记录已加入最小生成树的边的数量
36 int sum=0;//记录最小边权和
37 for(int i=1;i<=m;i++){
38 int x=find(a[i].start);
39 int y=find(a[i].end);
40 if(x!=y){//需要加边
41 unionn(x,y);
42 cnt++;
43 sum+=a[i].val;
44 }else{
45 continue;
46 }
47 if(cnt==n-1){//达到需要的总边数
48 break;
49 }
50 }
51 if(cnt==n-1){
52 cout<<sum<<endl;
53 }else{//建树失败
54 cout<<"orz"<<endl;
55 }
56 return 0;
57 }
P3366 模板最小生成树的更多相关文章
- [洛谷P3366] [模板] 最小生成树
存个模板,顺便复习一下kruskal和prim. 题目传送门 kruskal 稀疏图上表现更优. 设点数为n,边数为m. 复杂度:O(mlogm). 先对所有边按照边权排序,初始化并查集的信息. 然后 ...
- P3366 (模板)最小生成树
2019-01-30 最小生成树基本算法 定义: 给定一个边带权的无向图G=(V,E),n=|V|,m=|E|,由V中全部n个定点和E中n-1条边构成的无向连通子图被称为G的一颗生成树. 边的权值之和 ...
- 【洛谷 p3366】模板-最小生成树(图论)
题目:给出一个无向图,求出最小生成树,如果该图不连通,则输出orz. 解法:Kruskal求MST. 1 #include<cstdio> 2 #include<cstdlib> ...
- luoguP3366 [模板] 最小生成树
题目链接:https://www.luogu.org/problemnew/show/P3366 思路: 求最小生成树的模板题,求MST有两种算法——Prim.Kruskal. 两者区别:Prim在稠 ...
- 模板<最小生成树>
转载 最小生成树浅谈 这里介绍最小生成树的两种方法:Prim和Kruskal. 两者区别:Prim在稠密图中比Kruskal优,在稀疏图中比Kruskal劣.Prim是以更新过的节点的连边找最小值,K ...
- 模板——最小生成树prim算法&&向前星理解
通过最小生成树(prim)和最短路径优化引出的向前星存图,时至今日才彻底明白了.. head[i]存储的是父节点为i引出的最后一条边的编号, next负责把head[i]也就是i作为父节点的所有边连接 ...
- 模板——最小生成树kruskal算法+并查集数据结构
并查集:找祖先并更新,注意路径压缩,不然会时间复杂度巨大导致出错/超时 合并:(我的祖先是的你的祖先的父亲) 找父亲:(初始化祖先是自己的,自己就是祖先) 查询:(我们是不是同一祖先) 路径压缩:(每 ...
- P3366 【模板】最小生成树
原题链接 https://www.luogu.org/problemnew/show/P3366 一道最小生成树的模板题...... 昨天刚学最小生成树,wz大佬讲的一塌糊涂井然有序,所以我们今天做起 ...
- 洛谷P3366 【模板】最小生成树
P3366 [模板]最小生成树 319通过 791提交 题目提供者HansBug 标签 难度普及- 提交 讨论 题解 最新讨论 里面没有要输出orz的测试点 如果你用Prim写了半天都是W- 题目 ...
- P3366 【模板】最小生成树(boruvka/sollin)
P3366 [模板]最小生成树 boruvka/sollin 复杂度$O(mlogn)$ 简要说明一下过程 引入一个数组$link[i]$表示连通块$i$下一步可更新的最短的边的编号 1.每次枚举所有 ...
随机推荐
- shell mv cp image in parallel 多线程解压parallel
# apt install parallel # mkdir -p 1Kx1K/img # ls 1Kx1K/img_9*.jpg |parallel -j 80 mv {} 1Kx1K/img ht ...
- xshell拖拽文件
直接在linux中输入命令 yum install lrzsz 安装完毕后即可拖拽文件.
- Ubuntu22 vim配置
插件管理器 vim-plug # 下载插件管理器 sh -c 'curl -fLo ~/.vim/autoload/plug.vim --create-dirs \ https://raw.githu ...
- Open review Mitigating Propagation Failures in PINNs using Evolutionary Sampling
与Mitigating Propagation failures in PINNs using Evolutionary Sampling - Orange0005 - 博客园 (cnblogs.co ...
- llinux day02 基础操作 帮助 文件管理 马
免密码登录(只是为了方便教学,免了图形界面的密码) 1,Linux免密自动以root身份登录图形化界面,修改etc/gdm/custom.conf 在deamon下面添加两行,注意区分大小写 [dae ...
- python func_timeout 设置函数超时退出
使用func_timeout设置函数超时退出,使用func_set_timeout装饰器和func_timeout方法 from func_timeout import func_set_timeou ...
- 全国分乡镇第五次人口普查数据shp数据库省市区县街道
==名称:全国第五次人口普查任意十个乡镇的乡镇界地图==数据说明:精确到乡镇级别.==数据:面数据,属性列表(乡镇名.乡镇代码,第六次人口普查分乡镇属性数据)==时间:截止2000年12月31日==格 ...
- Win10家庭版安装docker desktop
1.开启Hyper-V在桌面新建hyperv.cmd文件,内容如下: pushd "%~dp0" dir /b %SystemRoot%\servicing\Packages\*H ...
- 【C学习笔记】day2-1 给定两个整形变量的值,将两个值的内容进行交换
#include<stdio.h> int main() { int a=0, b=1,temp; temp = b; b = a; a = temp; //printf("%d ...
- Java本地缓存解决方案---使用Google的CacheBuilder
一.背景 当业务实现上需要用到本地缓存,来解决一些数据量相对较小但是频繁访问数据的场景,可以采用Google的CacheBuilder解决方案. 二.代码实现 1. 首先在maven中引入下面的包 & ...