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.每次枚举所有 ...
随机推荐
- vs输出重定向
1.右键点击解决工程->项目属性 2.配置属性->生成事件->生成后事件 在命令行中输入:"$(TargetPath) >$(outdir)\1.txt" ...
- .NetCore自定义模板,发布Nuget
1.创建模板项目框架 2.创建模板文件 在项目文件夹根目录创建.template.config文件夹,在文件夹下创建新的文件:template.json 内容如下 { "$schema&qu ...
- ES 快速开始
ES语句构造麻烦,每次都拼,这次备份一下 1. 创建索引 PUT http://sae1002.qihoo.ai:9200/kosmos {"settings":{"in ...
- fftw安装
1. 下载fftw 2.tar -zxvf fftw.tar.gz 3. ./configure --prefix=path --enable-sse2 --enable-avx --enable-f ...
- vant-ui经验
1.van-checkbox搭配van-cell使用,点击圆圈区域,不触发定义的click函数. 解决:给van-checkbox添加一层div,添加click事件:van-checkbox也添加cl ...
- css - 预编译less下,解决深度选择器失效问题,完成css样式修改
#若深度选择器有效.使用此可修改样式 /deep/ .cube-btn{ //...自定义css样式 } #深度选择器失效,则: 1.重新定义deep深度选择器 @deep:~'>>> ...
- antd timePicker组件限制当前之前的时间不可选择
import React from 'react'; import ReactDOM from 'react-dom'; import {Input,DatePicker,Form,Col,Butto ...
- Selector 如何关联 channel,以及需要注意的点
一.创建 selector Selector selector = Selector.open(); 1.一个 selector 可以管理多个 channel . 二.channel 如何注册到 se ...
- java功能-发送http请求
一.发送json public void test() throws IOException { //参数封装--------------------------------------------- ...
- Mac下Apache Tomcat安装配置技巧
我们在MAC系统中查看网页时,一般都要使用到tomcat,这是因为appache只支持静态网页,但像asp,php,cgi,jsp等动态就需要tomcat来处理.那么该怎么在自己的MAC中安装tomc ...