【并查集】DZY loves graph

本文探讨了一种特殊的数据结构问题,通过启发式合并策略处理动态加边和删除节点操作,实现高效的最小生成树计算。文章详细介绍了算法流程,包括如何在加边时判断并避免重复连接,以及在删除节点时更新祖先节点大小和维护最小生成树状态。此外,还讨论了使用栈来存储和管理操作序列的方法。

传送门

官方题解

参考博客

本题有个特殊的性质,就是加边的时候可以保证边是从小到大加的,因为操作编号是从小到大的。

 

那么先考虑加边。如果这朵边的两个端点已经在同一个集合中,就可以不管这条边,但是还是要把这条边存到栈里!!因为到时候删边的时候要用。

如果这坨边连接了两个不连通的集合,就用启发式合并把这两个集合合并。这样可以保证复杂度是对的。

如果是路径压缩的话可以存在操作使其复杂度为O(n),然后一直撤销鬼畜就炸了。

 

然后如果Delete操作在Return操作前面可以事先存下结果直接输出。

Delete一个节点p的时候把p的所有祖先的siz减掉,把p的父亲置为它自己就行了。

用ans[x]存储当前有x条边的答案。

use_edge[d]=-1表示不需要d这条边,因为d两端早已连通,而后来的边权一定要大一些,一定不会用到最小生成树上。

如果需要这条边,use_edge[d]则表示合并的时候siz小一些的集合的那个根。后面删边要用。

注意,tot表示实际有多少条边,cnt_edge表示最小生成树(可能还未连通)上有多少条边,删边的时候注意减的顺序。

然后删的边用一个栈来维护就好。要开longlong。

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=5e5+10;
int n,m,a,b,k,fa[maxn],use_edge[maxn];
char op[maxn][10];int x[maxn],y[maxn],siz[maxn];
ll ans[maxn],cur;
stack<int> Q;
inline int read(){
	int x=0;char ch=getchar();
	while(!isdigit(ch)) ch=getchar();
	while(isdigit(ch)) x=(x<<3)+(x<<1)+ch-'0',ch=getchar();
	return x;
}
inline void print(ll x){
	if(x>9) print(x/10);
	putchar(x%10+'0');
}
inline int getfa(int x){return (fa[x]==x)?(x):(getfa(fa[fa[fa[x]]]));}
inline void Delete(int p){for(int u=fa[p];fa[u]!=u;u=fa[u])siz[u]-=siz[p];fa[p]=p;}
inline void addedge(int x,int y,int d){
	int px=getfa(x),py=getfa(y);Q.push(d);
	if(px==py){use_edge[d]=-1;return;}
	if(siz[px]>siz[py]) swap(px,py);
	fa[px]=py,siz[py]+=siz[px],use_edge[d]=px;
}
inline void solve(){
	int tot=0,cnt_edge=0;
	for(int i=1;i<=n;++i) fa[i]=i,siz[i]=1;
	for(int i=1;i<=m;++i){
		if(op[i][0]=='A'){
			addedge(x[i],y[i],i);
			if(use_edge[i]!=-1) cur+=i,cnt_edge++;
			ans[++tot]=(cnt_edge<n-1)?0:cur;
			print(ans[tot]),putchar('\n');
			if(op[i+1][0]=='R') op[i+1][0]='D',x[i+1]=1;
		}
		if(op[i][0]=='D'){
			if(op[i+1][0]=='R'){
				print(ans[tot-x[i]]),putchar('\n');
				print(ans[tot]),putchar('\n');
				continue;
			}
			while(x[i]--){
				int p=Q.top();Q.pop(),tot--;
				if(use_edge[p]==-1) continue;
				Delete(use_edge[p]),cur-=p,cnt_edge--;
			}
			ans[tot]=(cnt_edge<n-1)?0:cur;
			print(ans[tot]),putchar('\n');
		}
	}
}
int main(){
	n=read(),m=read();
	for(int i=1;i<=m;++i){
		scanf("%s",op[i]);
		if(op[i][0]=='A') x[i]=read(),y[i]=read();
		if(op[i][0]=='D') x[i]=read();
	}solve();
	return 0;
}

 

内容概要:本文介绍了一个基于MATLAB实现的无人机三维路径规划项目,采用蚁群算法(ACO)与多层感知机(MLP)相结合的混合模型(ACO-MLP)。该模型通过三维环境离散化建模,利用ACO进行全局路径搜索,并引入MLP对环境特征进行自适应学习与启发因子优化,实现路径的动态调整与多目标优化。项目解决了高维空间建模、动态障碍规避、局部最优陷阱、算法实时性及多目标权衡等关键技术难题,结合并行计算与参数自适应机制,提升了路径规划的智能性、安全性和工程适用性。文中提供了详细的模型架构、核心算法流程及MATLAB代码示例,涵盖空间建模、信息素更新、MLP训练与融合优化等关键步骤。; 适合人群:具备一定MATLAB编程基础,熟悉智能优化算法与神经网络的高校学生、科研人员及从事无人机路径规划相关工作的工程师;适合从事智能无人系统、自动驾驶、机器人导航等领域的研究人员; 使用场景及目标:①应用于复杂三维环境下的无人机路径规划,如城市物流、灾害救援、军事侦察等场景;②实现飞行安全、能耗优化、路径平滑与实时避障等多目标协同优化;③为智能无人系统的自主决策与环境适应能力提供算法支持; 阅读建议:此资源结合理论模型与MATLAB实践,建议读者在理解ACO与MLP基本原理的基础上,结合代码示例进行仿真调试,重点关注ACO-MLP融合机制、多目标优化函数设计及参数自适应策略的实现,以深入掌握混合智能算法在工程中的应用方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值