CSP刷题 201812-4 数据中心

本文介绍了如何运用Kruskal算法解决图的最小生成树问题,并着重强调在实现过程中如何避免超时,通过优化find_root函数来减少查找根节点的时间复杂度,最终找到最小生成树中的最长边。程序中展示了Kruskal算法的详细步骤,包括边的排序、树的合并等关键操作。

 题目说了一大堆废话,总结下来就是找到一个图的最小生成树,输出该树的最长边。

在这里我用Kruskal算法实现。

#include <iostream>
#include <algorithm>

using namespace std;

int n, m, root;

typedef struct edge {
	int x, y;
	int z;
} Edge;

bool compare(Edge e1, Edge e2) {
	return e1.z < e2.z;
}

Edge edges[100001];
int parent[50001];

int find_root(int x) {
	if (parent[x] == x) return x;
	else {
		parent[x] = find_root(parent[x]);
		return parent[x];
	}
}

void merge(int u, int v) {
	int r1 = find_root(u), r2 = find_root(v);
	parent[r2] = r1;
}

int main()
{
	cin >> n >> m >> root;
	for (int i = 0; i < m; i++) {
		int a0, a1, a2;
		cin >> a0 >> a1 >> a2;
		Edge e;
		e.x = a0;
		e.y = a1;
		e.z = a2;
		edges[i] = e;
	}
	sort(edges, edges + m,compare);
	for (int i = 0; i < n; i++) {
		parent[i] = i;
	}
	int n0 = 0, n1 = 0;
	while (n0 < n - 1)
	{
		if (find_root(edges[n1].x) != find_root(edges[n1].y)) {
			merge(edges[n1].x, edges[n1].y);
			n0++;
		}
		n1++;
	}
	cout << edges[n1-1].z << endl;
}

有几个需要注意的点。

第一,在merge函数中,一定要找到两个点在各自树中的根节点,将一个根节点设置为另一个根节点的父节点。

第二,程序很有可能出现运行超时的情况,例如我们将find_root函数修改如下,就会超时:

int find_root(int x) {
	if (parent[x] == x) return x;
	else {
		return find_root(parent[x]);
	}
}

这是因为树的高度太高了,寻找根节点的速度就慢。我们需要在每次寻找根节点的时候顺便更新一下parent。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值