[BJWC2010] 严格次小生成树(kruskal+树剖)

洛谷4180 【模板】严格次小生成树(最小生成树+树链剖分) 传送门 【题目分析】 首先明确一点:严格次小生成树与最小生成树有且只有一条边不同。 证明比较显然,自己画画图就行了,因为能替换的一定会构成一个环,依据这个就可以推出来。 同样,根据上面这个结论,我们可以枚举所有边,如果这条边不在生成树上,那么如果将这条边加入生成树中一定就会构成一个环,这时候只用将环上最大边删去即可,但考虑到严格次小生成树并且最大边可能与当前边权值相同,所以还要记录次大值。... 阅读详情

这题果然是模板题

一堆做法

但是根本思想是一样的

都是先跑一遍最小生成树,然后维护一下路径上最大值和小于最大值的最大值

主要的实现方法有三种

1.kruskal+倍增+lca

复杂度是O(mlogm)O(mlogm)O(mlogm),优点是复杂度低,常熟不是特别大,代码短,缺点是实现细节多

2.kruskal+lct

复杂度还是O(mlogm)O(mlogm)O(mlogm),优点是复杂度低,代码长度较短,缺点是常熟大,实现细节多

3.kruskal+树剖

复杂度是O(mlog2n)O(mlog^2n)O(mlog2n),优点是实现简单(只用考虑左右儿子的合并),细节少,(在同复杂度水平下)常熟小,缺点是复杂度有点高,代码长度大,但是这道题10510^5105级别的数据复杂度是正确的

所以我们主要来说一下这个树剖的做法(自认为是最稳的一种)

先跑一遍最小生成树,然后线段树维护最小生成树上的区间最大值和区间小于最大值的最大值

那么pushup大概是这个样子的

void pushup(int u){
	if(seg[lc]._max==seg[rc]._max)seg[u]._max=seg[lc]._max,seg[u].__max=max(seg[lc].__max,seg[rc].__max);
	else seg[u]._max=max(seg[lc]._max,seg[rc]._max),seg[u].__max=max(max(seg[lc].__max,seg[rc].__max),min(seg[lc]._max,seg[rc]._max));	
}

其中_max是最大值,__max是小于最大值的最大是变量名毒瘤勿喷

解释一下就是如果左右儿子的最大值相等,那么最大值就是这个值,次大值就是左右儿子的次大值中更大的那个

如果不等,最大值就是左右儿子中最大值较大的那个,次大值就是左右儿子中最大值较小的那个,或者是两个次大值中更大的那个,这两种情况去一个max(一定要注意取max要不然虽然能A但是是错的)

维护好这个之后,我们每次尝试加进去一条不是最小生成树上的边,这样会形成一个环,然后如果环上最大的那条边≥\geq≥要加进去的这条边就看第二大能不能加,然后算出来这条边加进去之后的最小生成树,最后统一取个min就可以了

几个问题

1.要开longlong,ans初值要大一点,否则wa#8

2.题目只说保证没有重边,没说保证没有自环,所以判断一下,否则wa#10

3.数组开的稍微大一点,否则re#10qwq

代码:

# include <bits/stdc++.h>
using namespace std;

# define Rep(i,a,b) for(int i=a;i<=b;i++)
# define _Rep(i,a,b) for(int i=a;i>=b;i--)
# define RepG(i,u) for(int i=head[u];~i;i=e[i].next)
# define debug puts("QAQ");

typedef long long ll;
const int N=2e5+5;
const int mod=1e9+7;
const double eps=1e-7;

template <typename T> void read(T &x){
	x=0;int f=1;
	char c=getchar();
	for(;!isdigit(c);c=getchar())if(c=='-')f=-1;
	for(;isdigit(c);c=getchar())x=(x<<1)+(x<<3)+c-'0';
	x*=f;
}

# define int long long

int n,m;
int head[N],cnt;
int faz[N],son[N],dep[N],siz[N],top[N],dfn[N],tot;
int sum,ans=1e18;
int val[N],_a[N];
int f[N];
bool vis[N];

struct Edge{
	int to,next,w;	
}e[N<<1];

void add(int x,int y,int c){
	e[++cnt]=(Edge){y,head[x],c},head[x]=cnt;	
}

struct edge{
	int x,y,c;
	bool operator < (const edge &cmp)const{
		return c<cmp.c;
	}
}a[N<<2];

int find(int x){
	if(f[x]==x)return x;
	return f[x]=find(f[x]);	
}

struct segment_tree{
	int l,r;
	int _max,__max;	
}seg[N<<2];

# define lc (u<<1)
# define rc (u<<1|1)

void pushup(int u){
	if(seg[lc]._max==seg[rc]._max)seg[u]._max=seg[lc]._max,seg[u].__max=max(seg[lc].__max,seg[rc].__max);
	else seg[u]._max=max(seg[lc]._max,seg[rc]._max),seg[u].__max=max(max(seg[lc].__max,seg[rc].__max),min(seg[lc]._max,seg[rc]._max));	
}

pair<int,int> merge(pair<int,int> l,pair<int,int> r){
	pair<int,int> res;
	if(l.first==r.first)res.first=l.first,res.second=max(l.second,r.second);
	else res.first=max(l.first,r.first),res.second=max(max(l.second,r.second),min(l.first,r.first));
	return res;	
}

void build(int u,int l,int r){
	seg[u].l=l,seg[u].r=r;
	if(l==r){seg[u]._max=_a[l];return;}
	int mid=l+r>>1;
	build(lc,l,mid);
	build(rc,mid+1,r);
	pushup(u);
}

pair<int,int> query(int u,int l,int r){
	if(seg[u].l>=l&&seg[u].r<=r)return make_pair(seg[u]._max,seg[u].__max);
	int mid=seg[u].l+seg[u].r>>1;
	if(r<=mid)return query(lc,l,r);
	if(l>mid)return query(rc,l,r);
	return merge(query(lc,l,r),query(rc,l,r));	
}

pair<int,int> RouteQuery(int x,int y){
	pair<int,int> res;
	while(top[x]!=top[y]){
		if(dep[top[x]]<dep[top[y]])swap(x,y);
		res=merge(res,query(1,dfn[top[x]],dfn[x]));
		x=faz[top[x]];
	}
	if(x!=y){
		if(dep[x]>dep[y])swap(x,y);
		res=merge(res,query(1,dfn[x]+1,dfn[y]));	
	}
	return res;
}

void dfs1(int u,int fa){
	faz[u]=fa;
	siz[u]=1;
	dep[u]=dep[fa]+1;
	RepG(i,u){
		int v=e[i].to;
		if(v==fa)continue;
		val[v]=e[i].w;
		dfs1(v,u);
		siz[u]+=siz[v];
		if(siz[v]>siz[son[u]])son[u]=v;	
	}
}

void dfs2(int u,int _top){
	top[u]=_top;
	dfn[u]=++tot;
	_a[tot]=val[u];	
	if(!son[u])return;
	dfs2(son[u],_top);
	RepG(i,u){
		int v=e[i].to;
		if(v==faz[u]||v==son[u])continue;
		dfs2(v,v);	
	}
}

void kruskal(){
	int tott=0;
	sort(a+1,a+m+1);
	Rep(i,1,m){
		int fax=find(a[i].x),fay=find(a[i].y);
		if(fax==fay)continue;
		vis[i]=true;
		f[fax]=fay;
		add(a[i].x,a[i].y,a[i].c),add(a[i].y,a[i].x,a[i].c);
		sum+=a[i].c;
		if(++tott==n-1)break;
	}
}

signed main()
{
	memset(head,-1,sizeof(head));
	read(n),read(m);
	Rep(i,1,n)f[i]=i;
	Rep(i,1,m){
		read(a[i].x),read(a[i].y),read(a[i].c);
		if(a[i].x==a[i].y)vis[i]=true;
	}
	kruskal();	
	dfs1(1,0),dfs2(1,1);
	build(1,1,n);
	Rep(i,1,m){
		if(vis[i])continue;
		int x=a[i].x,y=a[i].y,c=a[i].c;
		pair<int,int> res=RouteQuery(x,y);
		if(res.first<c)ans=min(ans,sum+c-res.first);
		else if(res.second&&res.second<c)ans=min(ans,sum+c-res.second);
	}
	printf("%lld\n",ans);
	return 0;
}

因为没有修改问题所以代码也不是很长,160+

update 2020.2.29 13:57 这题数据有点水,开始pushup写错了居然还A了

一定要注意考虑次大的也可能是最大的

ArcGIS Pro 制作这种地图海报 ArcMap 版本与 ArcGIS Pro 版本的制图功能相差太多,无论从美观上还是制图效率都远远优于 ArcMap,用了一段时间的 ArcGIS Pro ,真心推荐有条件的大家赶紧试一试!一个软件也能搞定一张不错的海报哦!----吐槽:好的设计真的是门花时间的活,这个教程大概花了我7小时左右,我都忘了我自己教程中截图多少张了!(可能是我速度太慢了)测试数据:阿里云盘分享-----北极海冰数据.https://www.aliyundrive.com/s/SUhsnqfkmXh。 阅读详情

相关推荐

c#源码,将矩阵(二维数组)渲染成云图,强度图,热力图,均匀性图,伪彩图

优快云软件0积分下载链接:https://download.youkuaiyun.com/download/wanghuannihao1992/86656759。6、渲染效果良好,颜色均匀分布,不存在等高线,交叉点。3、纯粹的C#代码编写,不含第三方dll或者控件。4、支持ColorBar显示,强度值颜色坐标显示。2、渲染时间60ms左右,速度快,1、二维数据最小支持2*2,7、采样全新数据插值算法。先直接上C#软件效果图。5、整图保存为单个图片。

业余程序员小徐的博客 6880

[BJWC2010] 严格次小生成树

思路: 1、用Kruskal算法,生成最小生成树,并保存MST的信息、边权和。 2、DFS分别维护路径上的最大值与次大值,我用的是倍增数组; 3、枚举所有未用的边,求出两点的LCA,可以用倍增或者Tarjan离线算法计算LCA。 4、求点到LCA的最大值边权,如果与查询的边权相同,则取其次大值。 5、用该边权减去两点到LCA的最大值,取所有差值中最小值,用原MST的边权和加上该差值的最小值即为严格次小生成树。

Ricky_One的博客 724

MatLab Desired port was :31515解决方案

前言:使用的MatLabR2022b今天突然出现了错误,在程序中打不开文件。后尝试了下面的方法,可以解决。后面还有另一种方法,上面方法如果行不通,大家可以尝试一下。搜索栏输入:firewall.cpl。找到相关项,右键属性,设置为允许。

qq_42212501的博客 1338

【题解】洛谷P4180 [BJWC2010] 严格次小生成树(最小生成树+倍增求LCA)

洛谷P4180:https://www.luogu.org/problemnew/show/P4180 前言 这可以说是本蒟蒻打过最长的代码了 思路 先求出此图中的最小生成树 权值为tot 我们称这棵树中的n-1条边为“树边” 其他m-n+1条边为“非树边” 枚举每条非树边(x,y,z)添加到最小生成树中 可以在x,y之间构成一个环 设x,y之间的路径最大值为val1...

186

深信服桌面云实战:从零部署到高效运维的配置全景指南

本文详细介绍了深信服桌面云从零部署到高效运维的全流程配置指南,涵盖硬件规划、平台部署、虚拟桌面发布、终端管理及性能优化等关键环节。特别强调了双万兆网络架构、分布式存储配置和智能调度功能的应用,帮助用户实现高性能、高可用的虚拟桌面环境。

weixin_28568819的博客 395

从零开始学习信号完整性(SIPI)--2

上一节我们已经谈过,信号完整性研究的是如何使驱动器输出的信号传输到接收器件并被正确的接收。 信号完整性的三要素包含了:信号、驱动接收芯片、传输通道。 这其中信号是主体,我们要做的主要工作就是设计好信号的传输路径为信号的正确传输扫清障碍。要做信号完整性分析与设计首先要了解信号的特性,以及信号质量的判别标准。 对一个信号进行描述通常需要如下几个指标: 信号特性的描述 摆幅:信号从低电平到高电平之间的电压差,对于单端信号通常由信号的供电电压决......

qq_29476769的博客 2万+

【模板】严格次小生成树[BJWC2010]

水模板

远行客 277

AI数字人:口播与唇形同步的福音,支持本地部署/批量生成/口齿清晰

你也可以直接输入语音,虚拟化身会根据语音的节奏和语调,同步做出相应的动作和表情,表现更加生动。不过这依然是个值得关注的工具。借助先进的 AI 算法,Heygem 高精度捕捉五官、轮廓等特征,构建逼真的虚拟模型。同时,它还能克隆语音,捕捉人声的细微特征,支持多种语音参数设置,打造高度相似的音色效果。打开设置,调整镜像存储位置,镜像文件比较大70~80G,选择合适的盘,设置完成后点击“Apply & Restart”。数字人视频画面与声音高度同步,口型匹配自然流畅,智能优化音视频效果,带来极佳的视听体验。

m0_72580657的博客 5861

次小生成树(树剖,生成树)

原文地址 生成树的概念: 在一个无向图中,设顶点数为\(n\),取其中\(n-1\)条边并使所有点相连,所得到的一棵树即为生成树。 最小生成树: 如果还没有接触过生成树的同学,欢迎戳->最小生成树详解 次小生成树: 次小生成树顾名思义,就是边权之和次小的一棵生成树。有严格次小生成树与非严格次小生成树之分。 尽管这个算法的名字叫做次小生成树,不过其实可以理解成一道数据结构 次小生成树...

667

docker部署zabbix6.2.7+grafana

docker部署zabbix6.2.7+grafana。

qq_48391148的博客 3654

华为OD机试2025C卷 - 字符串解密 (C++ & Python & JAVA & JS & GO)

华为OD机试 2025C卷 字符串解密,提供Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解

qq_45776114的博客 976

《P4180 [BJWC2010] 严格次小生成树》

摘要:题目要求求解无向图的严格次小生成树,即边权和严格大于最小生成树但小于其他所有生成树的生成树。给定N个点和M条带权边,需要找到这样的生成树并输出其边权和。关键点在于保证次小生成树严格大于最小生成树,且需要对大规模数据(N≤1e5,M≤3e5)高效处理。算法需先求最小生成树,再通过替换非树边并确保严格大于原权值来找到次小生成树。

Jasmine_llq的博客 864

【系统安全】Windows内核权限提升漏洞(CVE-2024-30088)

CVE-2024-30088是Windows内核提权漏洞,由越南安全研究员@Bùi Quang Hiếu详细分析。漏洞发生在AuthzBasepCopyoutInternalSecurityAttributes函数中,该函数在复制SecurityAttributesList时会使用用户提供的指针,在校验及复制期间存在时间差,导致存在TOCTOU漏洞。

李同學AI安全 1325

P4180 [BJWC2010] 严格次小生成树【题解】

摘要 本文介绍了求解严格次小生成树的算法。严格次小生成树是指边权和严格大于最小生成树但小于其他所有生成树的生成树。关键结论是:严格次小生成树与最小生成树仅相差一条边。算法步骤如下:1) 用Kruskal算法求出最小生成树;2) 对每个不在最小生成树中的边,计算将其加入后形成的环中的最大边(若与新边权值相同则取次大边);3) 通过替换操作得到新的生成树,取其中边权和最小的即为解。采用树上倍增方法优化查询过程,时间复杂度为O(nlogn+mlogn)。

cyx20091026的博客 728

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

【luogu P4180 严格次小生成树[BJWC2010]】 模板

题目链接:https://www.luogu.org/problemnew/show/P4180 这个题卡树剖。记得开O2。 这个题inf要到1e18。 定理:次小生成树和最小生成树差距只有在一条边上 非严格次小生成树:枚举每一条不在最小生成树上的边,加入到最小生成树中构成一个环。删去这个环上的最大值。(此最大值有可能与加入生成树中的边相等,故为非严格次小生成树。)重复此操作取min,得...

204

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

算法刷题【洛谷P4180 | BJWC2010】严格次小生成树

异想之旅:本人原创博客完全手敲,绝对非搬运,全网不可能有重复;本人无团队,仅为技术爱好者进行分享,所有内容不牵扯广告。本人所有文章仅在优快云、掘金和个人博客(一定是异想之旅域名)发布,除此之外全部是盗文! 洛谷 P4180 [BJWC2010]严格次小生成树 题目描述 小 C 最近学了很多最小生成树的算法,Prim 算法、Kruskal 算法、消圈算法等等。正当小 C 洋洋得意之时,小 P 又来泼小 C 冷水了。小 P 说,让小 C 求出一个无向图的次小生成树,而且这个次小生成树还得是严格次小的,也就是

异想之旅的博客 670

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

P4180 [BJWC2010]严格次小生成树

Description 小 C 最近学了很多最小生成树的算法,Prim 算法、Kurskal 算法、消圈算法等等。 正当小 C 洋洋得意之时,小 P 又来泼小 C 冷水了。小 P 说,让小 C 求出一个无向图的次小生成树,而且这个次小生成树还得是严格次小的,也就是说: 如果最小生成树选择的边集是 EM,严格次小生成树选择的边集是 ES,那么需要满足: (value(e) 表示边 e的权值) 这下小 C 蒙了,他找到了你,希望你帮他解决这个问题。 Input 第一行包含两个整数N 和M,表示无向图的点数与边

tylon2006的博客 166

洛谷 P4180 [BJWC2010]严格次小生成树

题目描述 小C最近学了很多最小生成树的算法,Prim算法、Kurskal算法、消圈算法等等。正当小C洋洋得意之时,小P又来泼小C冷水了。小P说,让小C求出一个无向图的次小生成树,而且这个次小生成树还得是严格次小的,也就是说:如果最小生成树选择的边集是EM,严格次小生成树选择的边集是ES,那么需要满足:和严格小于 这下小 C 蒙了,他找到了你,希望你帮他解决这个问题。 输入格式 第一行包含两个整数N...

zhn_666的博客 318

P4180 [BJWC2010] 严格次小生成树

最小生成树 LCA 树上倍增

linlinlin098765的博客 570

专题·次小生成树【including 八中生成树, 洛谷·【模板】严格次小生成树[BJWC2010]

初见安~本篇前置知识::最小生成树,最近公共祖先 1.次小生成树 次小生成树——说白了就是选的边与最小生成树不同并且满足边权和最小。这里的不同是指只要不是最小生成树选的边刚好都是次小生成树的边就可以了。 具体题目描述大概是这样的:【题目选择某入门OJ:八中生成树 Description 八中有N个建筑物,某两点间有一条边存在。上一任Boss建立了个最小生成树出来,这样全校就可以电话联系了...

樱狸✨愿携清风归来处 538

P4180 严格次小生成树[BJWC2010] Kruskal,倍增

题目链接\(Click\) \(Here\)。 题意就是要求一个图的严格次小生成树。以前被题面吓到了没敢做,写了一下发现并不难。 既然要考虑次小我们就先考虑最小。可以感性理解到一定有一种次小生成树,可以由最小生成树删一条边再加一条边得到。我们枚举加上去的这一条边,加上去以后原\(mst\)会成为一个基环树,想让它次小就在这个环里找一条最长的边(不包含新加进去的)删掉就好。放在树上来讲,就是找到\(...

weixin_34209406的博客 113

[BJWC2010]严格次小生成树

板子题 先kruskal得到最小生成树,再枚举未加进生成树中的边i,该边i和生成树树形成了一个环,选择这个环上最大的不等于i的权值的边去掉就得到一个新的树,所有这样得到的树权值之和即为次小生成树。 求环上最大边可以用倍增或者树链剖分,由于最大边可能和才加上去的边相等,所以还要维护一个次大边 #include<bits/stdc++.h> #define N 100005 #define...

weixin_30722589的博客 109

P4180 【模板】严格次小生成树[BJWC2010]

题目描述 小C最近学了很多最小生成树的算法,Prim算法、Kurskal算法、消圈算法等等。正当小C洋洋得意之时,小P又来泼小C冷水了。小P说,让小C求出一个无向图的次小生成树,而且这个次小生成树还得是严格次小的,也就是说:如果最小生成树选择的边集是EM,严格次小生成树选择的边集是ES,那么需要满足:(value(e)表示边e的权值)\sum_{e \in E_M}value(e)&...

216

【题解】洛谷P4180(同bzoj1977)[BJWC2010]【模板】严格次小生成树 LCA+kruskal

题目链接 输入输出格式 输入格式: 第一行包含两个整数N 和M,表示无向图的点数与边数。 接下来 M行,每行 3个数x y z 表示,点 x 和点y之间有一条边,边的权值为z。 输出格式: 包含一行,仅一个数,表示严格次小生成树的边权和。(数据保证必定存在严格次小生成树) 输入输出样例 输入样例#1: 5 6 1 2 1 1 3 2 2 4 3 3 5 4 3 4 3 4 5 6 输出样例#1:...

翻过这座山,他们就会听到你的故事 469

解题报告:luogu P4180 [BJWC2010]严格次小生成树(次小生成树、倍增LCA优化、O(mlogn) )

P4180 [BJWC2010]严格次小生成树 次小生成树有两种,一种是不严格次小生成树,也就是可以数值上等于最小生成树,一种是严格次小生成树,是权值严格大于最小生成树,两种求法大同小异。 方法2在严格次小生成树和不严格次小生成树都成立,而方法1只在严格次小生成树中成立 对于任意一颗最小生成树,都存在一个次小生成树(严格或者不严格都成立),与最小生成树只差1条边。 根据存在次小生成树与最小生成树只差一条边。 我们可以先通过kruskal求出最小生成树 O(mlogm) 通过这个树初始化某点到其他点的

繁凡さん的博客 521

[Luogu P4180][BJWC 2010]严格次小生成树

严格次小生成树,关键是“严格”,如果是不严格的其实只需要枚举每条不在最小生成树的边,如果得到边权和大于等于最小生成树的结束就行。原理就是因为Kruskal非常贪心,只要随便改一条边就能得到一个非严格的次小生成树。然而是严格的QAQ,于是得搞点别的东西来实现“严格”,维护个次大值就行。依次枚举每条边,如果这条边和加上这条边构成的环中最大的边边权相等,取次大值,否则取最大值。 参考代码: #i...

weixin_30852367的博客 172
上一篇: [NOIP2015] 运输计划
下一篇: [BJWC2010] 严格次小生成树(kruskal+lct)
NephrenRuqInsania
博客等级 码龄8年 20粉丝 115原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值