【一个蒟蒻的挣扎】最小生成树—Kruskal算法
济南集训第五天的东西,这篇可能有点讲不明白提前抱歉(我把笔记忘到别的地方了
最小生成树
概念:一个有 n 个结点的连通图的生成树是原图的极小连通子图,且包含原图中的所有 n 个结点,并且有保持图连通的最少的边。
在一给定的无向图G = (V, E) 中,(u, v) 代表连接顶点 u 与顶点 v 的边(即),而 w(u, v) 代表此边的权重,若存在 T 为 E 的子集(即)且为无循环图,使得 w(T) 最小,则此 T 为 G 的最小生成树。
最小生成树其实是最小权重生成树的简称。
最小生成树性质:设G=(V,E)是一个连通网络,U是顶点集V的一个非空真子集。若(u,v)是G中一条“一个端点在U中(例如:u∈U),另一个端点不在U中的边(例如:v∈V-U),且(u,v)具有最小权值,则一定存在G的一棵最小生成树包括此边(u,v)。
性质证明:
使用反证法证明;可参考旁边的图(画图画出来的,很丑见谅)
先做以下约定:①将集合U中的顶点看作是红色顶点,②而V-U中的顶点看作是蓝色顶点,③连接红点和蓝点的边看作是紫色边,④权最小的紫边称为轻边(即权重最"轻"的边)。于是,MST性质中所述的边(u,v)就可简称为轻边。
用反证法证明MST性质:
假设G中任何一棵MST(最小生成树)都不含轻边(u,v)。则若T为G的任意一棵MST,那么它不含此轻边。
根据树的定义,则T中必有一条从红点u到蓝点v的路径P,且P上必有一条紫边(u',v')连接红点集和蓝点集,否则u和v不连通。当把轻边(u,v)加入树T时,该轻边和P必构成了一个回路。删去紫边(u',v')后回路亦消除,由此可得另一生成树T'。
T'和T的差别仅在于T'用轻边(u,v)取代了T中权重可能更大的紫边(u',v')。因为w(u,v)≤w(u',v'),所以
w(T')=w(T)+w(u,v)-w(u',v')≤w(T)
即T'是一棵比T更优的MST,所以T不是G的MST,这与假设矛盾。
所以,MST性质成立。 ————以上来自于百度百科(卑微的蒟蒻)(他讲的比我好多了)
有两种算法可以求最小生成树,Prim算法和Kruskal算法
根据老师的说法prim不考(他也没上),所以这里只介绍Kruskal算法
kruskal算法
Kruskal算法所用的思想是贪心和并查集(所以还挺好理解的……吧……)
- 按照边权将边进行排序,然后从小到大连接最小的边(贪心)
- 若出现环,就跳过此边继续搜(用并查集判断)
- 直到已经使用的边数量为点数n-1(这点应该是由于树的性质?恳请大佬解答!!!)
——证明过程待填充——
思路部分看明白后大概就可以考虑代码了,想不出来欢迎来看一下我的程序(的注释)(仅能保证算法正确过得去洛谷模板题)
写的出来就可以跳过这段(写的也不咋样的)代码试试下面的题目了!
(洛谷模板题难度是 普及- 哦!!!努力努力肯定能想明白的!!!)
(当然如果你是大佬来挑错也非常欢迎……私信好吗?)
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int n,m;
struct edge
{
int u,v,w;
edge(){};
edge(int a,int b,int c)
{
u=a; v=b; w=c;
}
}E[];//建图存图
int ans=;
bool cmp(edge a,edge b)
{
return a.w<b.w;
}//结构体快排
int fa[];
int find(int x)
{
while(x!=fa[x]) x=fa[x]=fa[fa[x]];
return x;
}//并查集
int cnt;
void kruskal()
{
sort(E+,E+m+,cmp);//先对边进行排序
for (int i=; i<=m; i++)
{
int au=find(E[i].u),av=find(E[i].v);
if (au==av)
{
continue;
}//确定他们是否构成环(有同一个祖先),是的话就continue。
ans+=E[i].w;//将这个最小边权加入最后答案
fa[av]=au;//加入并查集
if (++cnt==n-)
{
break;
}//如果达到条件就退出
}
}
int main()
{
cin>>n>>m;
for (int i=; i<=n; i++)
{
fa[i]=i;
}//对并查集的初始化
for (int i=; i<=m; i++)
{
int a,b,c;
cin>>a>>b>>c;
E[i]=edge(a,b,c);//读入数据并存进边里
}
kruskal();//诺
cout<<ans;//输出答案!
return ;//——结——束——啦 ——!
}
代码看这里呐
多练练哦,板子是要背掉的(你的板子背了没?没)
可以的话继续往下
例题练手
这篇博客主要是介绍最小生成树和如何求最小生成树(Kruskal算法),讲题目并不是目的,所以这里只粘出了题目(我做过的相关的(我觉得海星的))和链接,有需要自行取用来练手,多练练总是好的
https://www.luogu.org/problem/P3366 【普及-】
- 这是个板子题啦,如果觉得我讲的很垃圾可以去看看题解,大概就能懂了,题解是大佬云集的地方呢(%%%)
https://www.luogu.org/problem/P1991 【普及+/提高】
- 要难一、、,多出了一种情况(还是最小生成树做,有大佬提出用瓶颈生成树然而——我并没有看懂)题目还行可以练练!
2019-09-2420:22:54
好的暂时先这么多,会在之后补充题目(加入好点的题删除不好的题)
好的!那么到这里就结束啦!
有看不懂的可以看看我里面提到的东西,我哪里写的不行也欢迎指正(私信)
那么这篇博客就到这里啦
感谢观看 ありがとうございます
【一个蒟蒻的挣扎】最小生成树—Kruskal算法的更多相关文章
- 【一个蒟蒻的挣扎】LCA (倍增)
#include<cstdio> #include<iostream> #include<cstring> using namespace std; struct ...
- 【一个蒟蒻的挣扎】单源最短路(Dijkstra)
赛前没啥时间好好解释了,还有三天2019CSP,大家加油啊!!! ヾ(◍°∇°◍)ノ゙ 背掉它就好啦!!! 我觉得我这一版打得还行就放上来了 #include<cstdio> #inclu ...
- 【转】最小生成树——Kruskal算法
[转]最小生成树--Kruskal算法 标签(空格分隔): 算法 本文是转载,原文在最小生成树-Prim算法和Kruskal算法,因为复试的时候只用到Kruskal算法即可,故这里不再涉及Prim算法 ...
- noip2013Day2T3-华容道【一个蒟蒻的详细题解】
描述 小 B 最近迷上了华容道,可是他总是要花很长的时间才能完成一次.于是,他想到用编程来完成华容道:给定一种局面,华容道是否根本就无法完成,如果能完成,最少需要多少时间. 小 B 玩的华容道与经典的 ...
- 最小生成树——kruskal算法
kruskal和prim都是解决最小生成树问题,都是选取最小边,但kruskal是通过对所有边按从小到大的顺序排过一次序之后,配合并查集实现的.我们取出一条边,判断如果它的始点和终点属于同一棵树,那么 ...
- 最小生成树------Kruskal算法
Kruskal最小生成树算法的概略描述:1 T=Φ:2 while(T的边少于n-1条) {3 从E中选取一条最小成本的边(v,w):4 从E中删去(v,w):5 if((v,w)在T中不生成环) { ...
- 求最小生成树——Kruskal算法
给定一个带权值的无向图,要求权值之和最小的生成树,常用的算法有Kruskal算法和Prim算法.这篇文章先介绍Kruskal算法. Kruskal算法的基本思想:先将所有边按权值从小到大排序,然后按顺 ...
- 一个蒟蒻对FFT的理解(蒟蒻也能看懂的FFT)
建议同学们先自学一下"复数(虚数)"的性质.运算等知识,不然看这篇文章有很大概率看不懂. 前言 作为一个典型的蒟蒻,别人的博客都看不懂,只好自己写一篇了. 膜拜机房大佬 HY 一. ...
- 最小生成树 kruskal算法&prim算法
(先更新到这,后面有时间再补,嘤嘤嘤) 今天给大家简单的讲一下最小生成树的问题吧!(ps:本人目前还比较菜,所以最小生成树最后的结果只能输出最小的权值,不能打印最小生成树的路径) 本Tianc在刚学的 ...
随机推荐
- 【线性代数】4-1:四个正交子空间(Orthogonality of the Four Subspace)
title: [线性代数]4-1:四个正交子空间(Orthogonality of the Four Subspace) categories: Mathematic Linear Algebra k ...
- 五一培训 清北学堂 DAY5
今天是吴耀轩老师的讲解- 今天的主要内容:图论 如何学好图论? 学好图论的基础:必须意识到图论! 图 邻接矩阵存图: 其缺点是显而易见的:1. 空间复杂度O(n^2)不能接受:2.有重边的时候很麻烦: ...
- python 绘制五角星
code import turtle n = eval(input("请输入五角星的长度")) turtle.begin_fill() #开始填充颜色 i = : turtle.f ...
- JavaWeb_(SSH)三大框架整合struts+hibernate+spring_Demo
三大框架整合 一.SSH导包 二.书写Spring 三.书写Struts 四.整合Spring与Struts 五.书写(与整合)Hibernate.引入c3p0连接池并使用hibernate模板 六. ...
- Java基础_通过模拟售票情景解决线程不安全问题
用代码来模拟铁路售票系统,实现通过四个售票点发售某日某次列车的100张车票,一个售票点用一个线程表示 第一种方法:通过继承Thread类的方法创建线程 package com.Gary1; publi ...
- 微信支付宝xposed个人收款免签支付源码
源码介绍: 个人免签支付是指使用自己的微信支付宝账号作为个人网站的收款账号,网站订单支付成功后,网站能实时收到成功回调信息. 系统基于xposed逆向微信.支付宝.云闪付来实现个人收款免 ...
- csp-s模拟84
T1: 考虑如何能按顺序生成光滑数.对每个质数用队列维护包含此质数的候选集合,每次从所有队首取出最小的作为一个光滑数,用每个质数乘上这个光滑数并加入相应候选集合.这样不会漏掉一个光滑数,但会有重复.比 ...
- Linux设备驱动程序 之 ioctl
ioctl 除了读取和写入设备之外,大部分驱动程序还需要另外一种能力,即通过设备驱动程序执行各种类型的硬件控制,通常这种需求使用ioctl方法支持,该方法实现了同名的系统调用: 在用户空间,ioctl ...
- 深度解析 Qt 中动态链接库
本文介绍的是Qt 中动态链接库,现在有些软件有自动升级功能,有些就是下载新的DLL文件,替换原来的动态链接库,MFC好象也有类似机制,Qt还有一种方式,就是把一个QWidget子类,编译成动态链接库. ...
- Flutter移动电商实战 --(3)底部导航栏制作
1.cupertino_IOS风格介绍 在Flutter里是有两种内置风格的: material风格: Material Design 是由 Google 推出的全新设计语言,这种设计语言是为手机.平 ...