首页 > 其他分享 >图的生成树及其简单应用

图的生成树及其简单应用

时间:2022-11-21 23:45:35浏览次数:71  
标签:连通 瓶颈 Kruskal 最小 生成 算法 应用 简单

OI-wiki 图论部分

有简单的东西,也有一些奇怪的算法。

总结: 学好 Kruskal 就对了.

0. 一点前置习题

1. luoguP4047 [JSOI2010]部落划分

实际上就是 Kruskal 做最小生成树, 将图从 \(k\) 个连通块变成 \(k-1\) 个连通块时所连的那条边的长度.
因为做最小生成树的时候各个连通块必然都是树, 所以说这等价于所用的第 \(n-k+1\) 条边, 不用维护连通块个数了.

int used=0;
for(int i=1;i<=cnt;i++)
{
    int fu=find(e[i].u),fv=find(e[i].v);
    if(fu==fv)continue;
    merge(fu,fv);
    used++;
    if(used==n-k+1)
    {
        printf("%.2lf\n",sqrt(e[i].val));
        return 0;
    }
}

2. luoguP3101 [USACO14JAN]Ski Course Rating G

还是一个 Kruskal 的过程. 维护每个连通块里有几个起点, 每次合成的连通块的大小大于 \(T\), 这个连通块对答案的贡献就是连通块内点的数量乘上连接两个连通块的边权.
算完之后记得把连通块的起点个数清零, 不要算重复了.

for(int i=1;i<=cnt;i++)
{
    int fu=find(e[i].u),fv=find(e[i].v);
    if(fu==fv)continue;
    if(siz[fu]+siz[fv]>=t)
    {
        ans+=e[i].val*(scnt[fu]+scnt[fv]);
        scnt[fu]=scnt[fv]=0;
    }
    merge(fu,fv);
}

3. luoguP1967 [NOIP2013 提高组] 货车运输

如果这是个树上问题, 那我们随便就维护了.
但其实在图上也没有多难, 仍然是考虑 Kruskal 的过程, 我们发现只需要建出原图的最大生成树, 然后在最大生成树上做询问就行了.
(代码懒得写了, 大概可以参考下一题)

4. CF609E Minimum spanning tree for each edge

首先我们求出最小生成树. 容易发现, 对于每条非树边, 它对应的生成树上的路径上的每条边的权值都(非严格)大于这条非树边.
那这个问题其实也就变得简单了, 我们只需要把生成树上边权最大的边删掉, 加上当前这条边, 就得到了经过这条边的最小生成树.

(代码咕咕咕)

1. Boruvka 算法

首先我们先复习一下 Kruskal 算法和 Prim 算法。
Kruskal 算法:加边加边加边,并查集查询!
Prim 算法:像 Dijkstra 一样每次取到连通块距离最小的点就完事了。

Boruvka 算法就比较神奇了。它和 Prim 算法比较像,但是是多路增广。
具体流程如下:

  • 初始时每个点是一个连通块。
  • 我们每次选择每个连通块并加入连向其他连通块的边权最小的边。
  • 重复算法直到每个连通分量都成为一个连通块。

容易发现在我们将边严格排序后,连边是不会出现环的。(因为连接两个连通块的最短的边只有那一条)
实现时用并查集维护连通块,并且注意一条边连接完两个连通块后,另一个连通块就不要再用这条边连回原来的连通块了。

(代码不写了)

虽然说这个算法比较冷门,但它并不是完全没用的。看下面的题:

CF888G Xor-MST

(咕咕咕)

2. 最小生成树的唯一性

考虑 Kruskal 的过程. 容易发现, 如果有权值相同的边, 并且实际使用的边的数量和最多能使用的边的数量(即连接后不会和先前的边形成环的边的数量)不同, 最小生成树就是不唯一的. 换句话说, 我们换个顺序跑 Kruskal 就会得到不同的最小生成树.
然后就做完了(

(并没有例题)

3. 次小生成树

luoguP4180 [BJWC2010] 严格次小生成树

首先我们考虑非严格次小生成树怎么做.
容易发现次小生成树和原生成树最多只有一条边的差异.
具体地, 我们考虑用一条非树边来替换原来生成树上的边, 容易发现替换生成树上对应链的最大值即可.

上面的做法是非严格的, 因为有可能替换的边和这条非树边的长度相同.
要求严格次小生成树, 我们还是用相同的思路, 但是当替换的边和这条非树边的长度相同时, 我们选择用链上的严格次大值来替换, 这样就保证了求出的生成树是严格次小的.

(代码咕咕咕)

4. 瓶颈生成树和最小瓶颈路

瓶颈生成树是最大边权值最小的生成树.
容易发现最小生成树一定是瓶颈生成树. 否则我们将原来最小生成树的最长边删掉, 然后用瓶颈生成树中的某一条边(显然存在)连接两部分, 得到的生成树的边权和就会更小, 这就产生了矛盾.
当然瓶颈生成树并不一定是最小生成树.

\(u\) 到 \(v\) 的最小瓶颈路定义为使得最大边权值最小的 \(u\) 到 \(v\) 的路径.
同样有结论, 最小生成树上 \(u\) 到 \(v\) 的路径一定是一条最小瓶颈路, 但是最小瓶颈路不一定是最小生成树上的路径.

总之, 瓶颈生成树和最小瓶颈路都不一定是唯一的, 但是它们的最大边的长度是唯一确定的, 可通过最小生成树求出.

(例题略)

5. Kruskal 重构树

6. 最小树形图

7. 最小直径生成树

标签:连通,瓶颈,Kruskal,最小,生成,算法,应用,简单
From: https://www.cnblogs.com/pjykk/p/16541855.html

相关文章

  • oracle中函数的简单使用
    --status为空返回3,不为空显示本身的值select*frompublic_memoccwherenvl(cc.status,'3')!='4'  --status为空显示数据为空,不为空显示本身的值s......
  • 使用C#简单制作一个看门狗程序
    摘要在有些特殊项目中,软件可能是无人值守的,如果程序莫名其妙挂了或者进程被干掉了等等,这事开发一个看门狗程序是非常有必要的,它就像一只打不死的小强,只要程序非正常退出,它......
  • <二>自己实现简单的string
    我们结合运算符重载知识实现string类在自己实现的String类中可以参考C++中string的方法例如构造,加法,大小比较,长度,[]等操作.当前的MyString类中,暂时不加入迭代器,我......
  • Python 多进程(一)简单场景
    需求:使用多进程,把add的结果放进list原始的多进程之间不能共享数据使用Manager来管理list,多进程可以操作同一个list使用multiprocessing.Manager().list()创建一个listd......
  • win10 应用商店无法打开
    win10应用商店无法打开http://www.ithome.com/html/win10/174708.htm修复方法:•首先,点此打开官方页面,如下图所示:Win10应用商店打不开?微软官方提供修复方法•点击“......
  • 从 docker 容器反向生成 docker-compose yml 文件
    问题场景docker-compose.yml被不小心删除了,但是容器还在没有使用docker-compose管理的容器现在想迁移到docker-compose上反向生成docker-compose.yml文件使用......
  • 小公司的应用服务部署历程
    先声明一下:我所在的公司是一个小团队,做物联网相关的,前后端、硬件、测试加起来也就五六十个人左右;本人的岗位是Java开发(兼DBA、运维。。。);我进公司时整个项目的部署架构为......
  • 深度优先生成树和广度优先生成树的详解版
    其实在对无向图进行遍历的时候,遍历过程中所经历过的图中的顶点和边的组合,就是图的生成树或者生成森林。图1无向图 例如,图1中的无向图是由V1~V7的顶点和编号分......
  • 【Azure 应用服务】Azure Powershell Function 出错 The term 'Connect-AzAccount' is
    问题描述在AzureFunction中,执行Powershell的Function脚本时,先后出现1:[Error]ERROR:Theterm'Connect-AzAccount'isnotrecognizedasanameofacmdlet,functio......
  • IDEA生成eurekaServer端服务注册中心
    1、建Module2、改POM<!--eureka-server--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-s......