次小生成树学习笔记

次小生成树有严格次小生成树和非严格次小生成树之分。常见的是严格次小生成树。

严格次小生成树的定义如下:

如果最小生成树选择的边集是 E M E_M EM,严格次小生成树选择的边集是 E S E_S ES,那么需要满足:( v a l u e ( e ) value(e) value(e) 表示边 e e e 的权值) ∑ e ∈ E M v a l u e ( e ) < ∑ e ∈ E S v a l u e ( e ) \sum_{e \in E_M}value(e)<\sum_{e \in E_S}value(e) eEMvalue(e)<eESvalue(e)

——P4180 [BJWC2010] 严格次小生成树


求严格次小生成树的方法主要有倍增、树剖、LCT 等。这里介绍所用算法较基础的 Kruskal+倍增+LCA 的方法。

显然,次小生成树是在最小生成树的基础上替换一条边之后形成的。

容易想到一种思路:对于每一条非树边,尝试把它加入最小生成树中。此时图中出现了一个环,删去环中边权最大的树边即可。由于要求的是严格次小,为了避免最大树边等于加入的这条非树边的边权的情况,还需要维护次大树边。

维护次大树边可以用倍增。用 g 1 ( i , j ) , g 2 ( i , j ) g_1(i,j),g_2(i,j) g1(i,j),g2(i,j) 分别表示从 i i i i i i 2 j 2^j 2j 级父亲的路径上的边权最大值、次大值。 g 1 g_1 g1 直接维护即可, g 2 g_2 g2 max ⁡ \max max 选择需要分情况讨论:

  • g 1 g_1 g1 ( i , i + 2 j − 1 ) , ( i + 2 j − 1 , i + 2 j ) (i,i+2^{j-1}),(i+2^{j-1},i+2^j) (i,i+2j1),(i+2j1,i+2j) 两段最大值相等,维护 g 2 g_2 g2 的两段最大值。
  • g 1 ( i , j − 1 ) > g 1 ( i + 2 j − 1 , j − 1 ) g_1(i,j-1)>g_1(i+2^{j-1},j-1) g1(i,j1)>g1(i+2j1,j1),则次大值不可能在后面的区间出现,维护前面区间的次大值和后面区间的最大值取 max ⁡ \max max 即可。
  • g 1 ( i , j − 1 ) < g 1 ( i + 2 j − 1 , j − 1 ) g_1(i,j-1)<g_1(i+2^{j-1},j-1) g1(i,j1)<g1(i+2j1,j1),则次大值不可能在前面的区间出现,维护后面区间的次大值和前面区间的最大值取 max ⁡ \max max 即可。

时间复杂度 O ( n log ⁡ n + m log ⁡ n ) O(n\log n+m\log n) O(nlogn+mlogn)

#include <bits/stdc++.h>
using namespace std;
#define int long longconst int maxn=1e5+5,maxm=6e5+5;
int head[maxn],g1[maxn][25],g2[maxn][25],f[maxn][25],dep[maxn],cnt,N,M,fa[maxn],sum;
struct edge1{int u,v,w;}e1[maxm];
struct edge2{int to,nxt,w;}e2[maxm];
bool vis[maxm];bool cmp(edge1 a,edge1 b){return a.w<b.w;}int find(int x){return x==fa[x]?x:fa[x]=find(fa[x]);}void add(int x,int y,int z){e2[++cnt]={y,head[x],z},head[x]=cnt;}void kruskal()
{sort(e1+1,e1+M+1,cmp);int tot=0;for(int i=1;i<=M;i++){int fu=find(e1[i].u),fv=find(e1[i].v);if(fu!=fv) tot++,fa[fu]=fv,sum+=e1[i].w,add(e1[i].u,e1[i].v,e1[i].w),add(e1[i].v,e1[i].u,e1[i].w),vis[i]=1;if(tot==N-1) break;}
}void dfs(int x,int fa)
{dep[x]=dep[fa]+1,f[x][0]=fa;for(int i=1;i<=20;i++){f[x][i]=f[f[x][i-1]][i-1];g1[x][i]=max(g1[f[x][i-1]][i-1],g1[x][i-1]);if(g1[f[x][i-1]][i-1]==g1[x][i-1]) g2[x][i]=max(g2[x][i-1],g2[f[x][i-1]][i-1]);else if(g1[f[x][i-1]][i-1]>g1[x][i-1]) g2[x][i]=max(g1[x][i-1],g2[f[x][i-1]][i-1]);else g2[x][i]=max(g2[x][i-1],g1[f[x][i-1]][i-1]);}for(int i=head[x];i;i=e2[i].nxt){if(e2[i].to==fa) continue;g1[e2[i].to][0]=e2[i].w;dfs(e2[i].to,x);}
}int lca(int x,int y)
{if(dep[x]<dep[y]) swap(x,y);for(int i=20;i>=0;i--) if(dep[f[x][i]]>=dep[y]) x=f[x][i];if(x==y) return x;for(int i=20;i>=0;i--)if(f[x][i]!=f[y][i]) x=f[x][i],y=f[y][i];return f[x][0];
}int getmx(int x,int rt,int w)
{int ans=0;for(int i=20;i>=0;i--)if(dep[f[x][i]]>=dep[rt]){if(g1[x][i]==w) ans=max(ans,g2[x][i]);else ans=max(ans,g1[x][i]);x=f[x][i];}return ans;
}signed main()
{cin>>N>>M;for(int i=1;i<=M;i++) cin>>e1[i].u>>e1[i].v>>e1[i].w;for(int i=1;i<=N;i++) fa[i]=i;kruskal();dfs(1,0);int ans=LLONG_MAX;for(int i=1;i<=M;i++){if(e1[i].u==e1[i].v||vis[i]) continue;int mx=getmx(e1[i].u,lca(e1[i].u,e1[i].v),e1[i].w),my=getmx(e1[i].v,lca(e1[i].u,e1[i].v),e1[i].w);if(max(mx,my)!=e1[i].w) ans=min(ans,sum+e1[i].w-max(mx,my));}cout<<ans<<endl;// for(int i=1;i<=N;i++) cout<<g1[i][0]<<' '<<g2[i][0]<<endl;return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/131719.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring Boot 面试题——常用注解

目录 Spring Bean将一个类声明为 Bean自动装配 Bean声明 Bean 的作用域 前端后传值处理常见的 HTTP 请求类型读取配置文件定时任务全局 Controller 层异常处理 Spring Bean 将一个类声明为 Bean Component&#xff1a;通用的注解&#xff0c;可标注任意类为 Spring 组件。如果…

【入门Flink】- 04Flink部署模式和运行模式【偏概念】

部署模式 在一些应用场景中&#xff0c;对于集群资源分配和占用的方式&#xff0c;可能会有特定的需求。Flink为各种场景提供了不同的部署模式&#xff0c;主要有以下三种&#xff1a;会话模式&#xff08;Session Mode&#xff09;、单作业模式&#xff08;Per-Job Mode&…

小程序如何设置用户同意服务协议并上传头像和昵称

为了保护用户权益和提供更好的用户体验&#xff0c;设置一些必填项和必读协议是非常必要的。首先&#xff0c;用户必须阅读服务协议。服务协议是明确规定用户和商家之间权益和义务的文件。通过要求用户在下单前必须同意协议&#xff0c;可以确保用户在使用服务之前了解并同意相…

【机器学习】随机森林

随机森林 文章目录 随机森林1. 什么是集成学习方法2. 随机森林3. 随机森林工作过程4. API5. 总结 1. 什么是集成学习方法 集成学习方法通过建立几个模型组合来解决单一预测问题。它的工作原理就是生成多个分类器/模型&#xff0c;各自独立地学习和做出预测。这些预测最后结合成…

分析:如何多线程运行测试用例

这是时常被问到的问题&#xff0c;尤其是UI自动化的运行&#xff0c;过程非常耗时&#xff0c;所以&#xff0c;所以多线程不失为一种首先想到的解决方案。 多线程是针对的测试用例&#xff0c;所以和selenium没有直接关系&#xff0c;我们要关心的是单元测试框架。 unittest …

Spring IOC - Spring启动过程解析

Spring启动流程的核心逻辑主要体现在方法AbstractApplicationContext#refresh中&#xff0c;该方法没有被子类重写。 本文主要从宏观层面对其进行剖析&#xff0c;从整体上感知。各执行步骤和作用按先后顺序如下表所示&#xff0c;其中标红方法为核心方法&#xff0c;标绿色方法…

[GDOUCTF 2023]<ez_ze> SSTI 过滤数字 大括号{等

SSTI模板注入-中括号、args、下划线、单双引号、os、request、花括号、数字被过滤绕过&#xff08;ctfshow web入门370&#xff09;-CSDN博客 ssti板块注入 正好不会 {%%}的内容 学习一下 经过测试 发现过滤了 {{}} 那么我们就开始吧 我们可以通过这个语句来查询是否存在ss…

免费亲人微信聊天记录提取软件新版本v1.1,使用说明,注意事项 2023.11.06

V 1.1 优化了备份速度&#xff0c;新增了备份消息类型的选型&#xff0c;可以选择仅仅备份文本&#xff0c;或者文本与音频&#xff0c;或者文本音频视频图片。 有什么办法可以导出与某个人的微信聊天记录&#xff1f; 只想导出与某个微信好友的聊天记录&#xff0c;有办法做到…

内网服务器(不通外网)访问高德在线地图服务的方法

在项目部署过程中&#xff0c;若部署服务器处于内网环境&#xff0c;则无法调用高德服务。需要通过搭建代理实现请求的转发&#xff0c;从而获取到在线服务内容。下面的记录解决了内网服务器访问高德地图服务的问题。 一、所需设备 内网服务器&#xff08;项目所需部署环境&a…

运维知识点-MySQL从小白到入土

MySQL从小白到入土 mysql 服务器安装windows mysql 服务漏洞复现-mysql jdbc反序列化-权限绕过 mysql 服务器安装 https://dev.mysql.com/downloads/mysql/https://www.cnblogs.com/xiaostudy/p/12262804.html 点餐小程序腾讯云服务器安装mysql8 windows mysql 服务 net sta…

1.UML面向对象类图和关系

文章目录 4种静态结构图类图类的表示类与类之间的关系依赖关系(Dependency)关联关系(Association)聚合(Aggregation)组合(Composition)实现(Realization)继承/泛化(Inheritance/Generalization)常用的UML工具reference欢迎访问个人网络日志🌹🌹知行空间🌹🌹 4种静态结构…

cp没有--exclude选项!Linux复制文件夹时如何排除一些文件?

之前使用tar命令压缩文件将时&#xff0c;使用了–exclude选项排除了一些不需要的文件。现在我想复制一个文件夹&#xff0c;但是其中一些文件不需要复制&#xff0c;此时注意到cp命令居然没有–exclude选项。 rsync可以快速地帮助我们完成相同的事情&#xff0c;命令如下&…

rust 基础数据类型

默认类型 大部分情况下&#xff0c;rust 可以基于上下文自动推导出变量的类型。下面代码中&#xff0c;变量 x 没有显式&#xff0c;rust 默认是 i32 类型。 fn main() {let x 5; }但也有一些例外情况&#xff0c;比如&#xff0c;字符串类型的转换中变量 x 的类型&#xff…

【Java 进阶篇】JSP 简单入门

在现代Web开发中&#xff0c;JavaServer Pages&#xff08;JSP&#xff09;是一项非常重要的技术。JSP允许开发者将Java代码嵌入HTML页面&#xff0c;以实现动态内容的生成和呈现。本文将详细介绍JSP的概念、原理以及如何使用JSP来构建Web应用程序。 第一部分&#xff1a;JSP …

如何将 XxlJob 集成达梦数据库

1. 前言 在某些情况下&#xff0c;你的项目可能会面临数据库选择的特殊要求&#xff0c;随着国产化的不断推进&#xff0c;达梦数据库是一个常见的选择。本篇博客将教你如何解决 XxlJob 与达梦数据库之间的 SQL 兼容性问题&#xff0c;以便你的任务调度系统能够在这个数据库中…

章鱼网络进展月报 | 2023.10.1-10.31

章鱼网络大事摘要 1、Louis 成功竞选 NDC 的 HoM 议席&#xff0c;将会尽最大努力推动 NEAR 变革。2、章鱼网络受邀参加在土耳其主办的 Cosmoverse2023&#xff0c;分享 Adaptive IBC 的技术架构。3、2023年10月8日章鱼日&#xff0c;是章鱼网络主网上线2周年的纪念日。 …

机器学习---SVM目标函数求解,SMO算法

1. 线性可分支持向量机 1.1 定义输入数据 假设给定⼀个特征空间上的训练集为&#xff1a; 其中&#xff0c;(x , y )称为样本点。 x 为第i个实例&#xff08;样本&#xff09;。 y 为x 的标记&#xff1a; 当y 1时&#xff0c;x 为正例&#xff1b;当y −1时&#xff0c;x…

vue3项目实践

创建 vue3 项目 node本版&#xff1a;node 16.x.x&#xff0c; 脚手架&#xff1a;create-vue 脚手架工具&#xff0c;底层vite 创建vue3项目&#xff1a;npm init vuelatest setup函数 vue3 单文件组件 1、vite.config.js配置文件基于vite的配置 2、template模板不再要求唯…

NOIP2023模拟10联测31 游戏

题目大意 Alice \text{Alice} Alice和 Bob \text{Bob} Bob在玩一个游戏&#xff1a;有一个由正整数组成的集合 S S S&#xff0c;两人轮流从中选数&#xff0c; Alice \text{Alice} Alice先手。每次一个人可以从当前集合中选一个数 x x x&#xff0c;把 x x x以及 x x x在集合中…

docker compose实现容器编排

Compose 使用的三个步骤&#xff1a; 使用 Dockerfile 定义应用程序的环境 使用 compose.yml 定义构成应用程序的服务&#xff0c;这样它们可以在隔离环境中一起运行 最后&#xff0c;执行 docker compose up 命令来启动并运行整个应用程序 为什么需要docker compose Dock…