第十一届蓝桥杯大赛软件类省赛:试题J:网络分析

本文介绍如何使用并查集数据结构优化网络分析中的节点连接操作,通过树的压缩减少查找同一集合节点的时间复杂度。展示了C++代码实现及应用实例,包括myfind函数查找祖先节点和join函数合并集合。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

第十一届蓝桥杯大赛软件类省赛:试题J:网络分析

原题:

在这里插入图片描述
在这里插入图片描述
利用并查集把相互连接的节点并入同一集合,因为并查集中实现了树的压缩,所以循环遍历查找在同一集合中节点的操作复杂度比较低。

#include <iostream>
using namespace std;

int arr[100001];			//记录集合信息
int num[100001] = { 0 };	//记录储存信息大小

int myfind(int i) {			//实现查找祖先节点并缩短树高,使其子代节点向父节点集中
	if (arr[i] < 0)			//数组的初始化是祖先为自身,即节点值为下标
		return i;			//祖先为自身即返回
	return arr[i] = myfind(arr[i]);		//如果祖先不是自身,递归查找祖先,同时将当前节点和随后的父节点连接到祖先节点上,简化树
}
void join(int a, int b) {	//将ab组合加入到集合中
	int fa = myfind(a);		//拿到a和b的祖先
	int fb = myfind(b);
	int temp = arr[fa] + arr[fb];
	if (fa != fb) {			//判断ab是否为同一祖先
		if (fa < fb) {		//如果fa更小,说明此集合节点更多
			arr[fb] = fa;	//就把fb为祖先的集合连接到fa上
			arr[fa] = temp;	//更新祖先fa的节点数量
		}
		else {
			arr[fa] = fb;
			arr[fb] = temp;
		}
	}
}

int main() {
	for (int i = 1; i <= 100001; i++) {			//初始化为-1,即全部为根节点
		arr[i] = -1;
	}
	int n, m;
	cin >> n >> m;
	int op, a, b;
	for (int i = 0; i < m; i++) {
		cin >> op >> a >> b;
		if (op == 1) {
			join(a, b);		//将a,b并入一个集合
		}
		else if (op == 2) {
			int fa = myfind(a);		//查找a的祖先
			for (int i = 1; i <= n; i++) {		//循环查找与a同祖先的节点
				if (fa == myfind(i)) {
					num[i] += b;
				}
			}
		}
	}
	for (int i = 1; i <= n; i++) {
		cout << num[i] << " ";
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值