题目描述

如题,给出一个无向图,求出最小生成树,如果该图不连通,则输出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 模板最小生成树的更多相关文章

  1. [洛谷P3366] [模板] 最小生成树

    存个模板,顺便复习一下kruskal和prim. 题目传送门 kruskal 稀疏图上表现更优. 设点数为n,边数为m. 复杂度:O(mlogm). 先对所有边按照边权排序,初始化并查集的信息. 然后 ...

  2. P3366 (模板)最小生成树

    2019-01-30 最小生成树基本算法 定义: 给定一个边带权的无向图G=(V,E),n=|V|,m=|E|,由V中全部n个定点和E中n-1条边构成的无向连通子图被称为G的一颗生成树. 边的权值之和 ...

  3. 【洛谷 p3366】模板-最小生成树(图论)

    题目:给出一个无向图,求出最小生成树,如果该图不连通,则输出orz. 解法:Kruskal求MST. 1 #include<cstdio> 2 #include<cstdlib> ...

  4. luoguP3366 [模板] 最小生成树

    题目链接:https://www.luogu.org/problemnew/show/P3366 思路: 求最小生成树的模板题,求MST有两种算法——Prim.Kruskal. 两者区别:Prim在稠 ...

  5. 模板<最小生成树>

    转载 最小生成树浅谈 这里介绍最小生成树的两种方法:Prim和Kruskal. 两者区别:Prim在稠密图中比Kruskal优,在稀疏图中比Kruskal劣.Prim是以更新过的节点的连边找最小值,K ...

  6. 模板——最小生成树prim算法&&向前星理解

    通过最小生成树(prim)和最短路径优化引出的向前星存图,时至今日才彻底明白了.. head[i]存储的是父节点为i引出的最后一条边的编号, next负责把head[i]也就是i作为父节点的所有边连接 ...

  7. 模板——最小生成树kruskal算法+并查集数据结构

    并查集:找祖先并更新,注意路径压缩,不然会时间复杂度巨大导致出错/超时 合并:(我的祖先是的你的祖先的父亲) 找父亲:(初始化祖先是自己的,自己就是祖先) 查询:(我们是不是同一祖先) 路径压缩:(每 ...

  8. P3366 【模板】最小生成树

    原题链接 https://www.luogu.org/problemnew/show/P3366 一道最小生成树的模板题...... 昨天刚学最小生成树,wz大佬讲的一塌糊涂井然有序,所以我们今天做起 ...

  9. 洛谷P3366 【模板】最小生成树

    P3366 [模板]最小生成树 319通过 791提交 题目提供者HansBug 标签 难度普及- 提交  讨论  题解 最新讨论 里面没有要输出orz的测试点 如果你用Prim写了半天都是W- 题目 ...

  10. P3366 【模板】最小生成树(boruvka/sollin)

    P3366 [模板]最小生成树 boruvka/sollin 复杂度$O(mlogn)$ 简要说明一下过程 引入一个数组$link[i]$表示连通块$i$下一步可更新的最短的边的编号 1.每次枚举所有 ...

随机推荐

  1. uniapp 样式记录

    flex https://uniapp.dcloud.io/nvue-css display: flex;/* 容器布局 */ flex:1; overflow: scroll;/* 容器内滚动条 * ...

  2. [Oracle19C 数据库管理] 配置数据库审计

    以下内容未经整理 占位 强制审计:无法关闭此审计,比如记录数据库的开启和关闭. 标准审计: 基于值得审计:创建触发器,基于值进行记录.Trigger占用资源多 细粒度审计:加一些where条件,针对触 ...

  3. python单机版自动化测试框架源代码(selenium+Appium+requests+unittest+Excel用例+HTMLTestRunner报告)

    一.自动化测试框架: 1.框架和项目源代码下载 https://gitee.com/rmtic/autoTest 说明:框架可以支持web界面UI.安卓Android,ios苹果.接口API等自动化测 ...

  4. Redis缓存中的数据和数据库不一致

    首先关于两者数据的一致性包含有两种情况: (1)缓存中有数据时,那数据库中的数据要和缓存中的数据相同: (2)缓存中没有数据时,数据库中的数据必须是最新的. 如果不符合以上两种情况,就属于缓存和数据库 ...

  5. koa源代码解析

    koa不愧为小而美,主要代码很少.简单来说,1,koa封装了node的http.createServer((req,res)=>{})的入参req,res到ctx同名属性(一个自定义对象)中,并 ...

  6. 在集群上运行Spark应用

    初识Spark真的存在很多疑问:Spark需要部署在集群里的每个节点上吗?Spark怎么有这么多依赖,这些依赖分别又有什么用?官网里边demo是用sbt构建的,难道还有再学一下sbt吗? --就是这么 ...

  7. npm 使用阿里源

    npm config set registry https://registry.npm.taobao.org/ npm config get registry 安装vue-cli 报错 npm in ...

  8. sqlsugar 更新某列数据 UpdateColumns 与SetColumns 使用区别

    第一种方式 UpdateColumns public int updateLogPath(int TeamID, string logoPath) { Team t = new Team(); t.T ...

  9. c#遍历一个对象的字段信息

    c#遍历对象字段 场景:有一个对象作为导出word段落的数据.每一个字段就代表一个段落,可以对相应段落数据设置样式(字体.颜色.加粗--) 参考文献:(12条消息) C#获取实体类字段信息Proper ...

  10. H5分享功能--带图标、说明

    代码实现 index.vue <template> <div id="app"> <SelfSharePage v-if="share_da ...