数据中心 最小生成树

题意:

在这里插入图片描述

思路:

观察题目,我们可以将题意简化为:一个无向图中,每条边具有不同的权重,我们需要找到一个最优生成树,使得这个树中的最大边权最小。因此题目就转化成了最小生成树问题。

采用结构体来存储边,结构体里的数据变量为两顶点和边的权重,将边存入到一个边数组里,采用kruskal算法求得最小生成树,结果便是这棵最小生成树中的最大边的值。
(关于kruskal算法的注意点,可以看我之前写的blog: https://blog.csdn.net/FoxMakarov/article/details/105169919)


总结:

有时候题目会非常繁琐,我们需要将复杂的题意转化为简单的问题

求得最小生成树问题可以采用kruskal算法。


代码:

#include<stdio.h>
#include<algorithm>

int par[50001] = { 0 };
int Rank[50001] = { 0 };

struct Edge
{
	int u;
	int v;
	int w;

	Edge(int _u = 0, int _v = 0, int _w = 0) :u(_u), v(_v), w(_w) {}
	Edge(const Edge& t) :u(t.u), v(t.v), w(t.w) {}

	bool operator<(const Edge& t)const
	{
		return w < t.w;
	}
};

int find(int i)
{
	if (i == par[i])
		return i;
	else return par[i] = find(par[i]);
}

bool unite(int i, int j)
{
	int par1 = find(i);
	int par2 = find(j);
	if (par1 == par2)return false;//****************************已经在一个并查集里了
	if (Rank[par1] < Rank[par2])
	{
		Rank[par2] += Rank[par1];
		par[par1] = par2;
	}
	else
	{
		Rank[par1] += Rank[par2];
		par[par2] = par1;
	}
	return true;
}

Edge edge[100001];

int main()
{
	int n;
	long long m;
	int root;
	scanf_s("%d %lld %d", &n, &m, &root);
	for (int i = 0; i < n; i++)
	{
		par[i] = i;
		Rank[i] = 1;
	}
	for (long long i = 0; i < m; i++)
	{
		int u, v;
		long long w;
		scanf_s("%d %d %lld", &u, &v, &w);
		edge[i] = Edge(u, v, w);
	}
	std::sort(edge, &edge[m]);
	long long ans = -1;
	for (int i = 0; i < m; i++)
	{
		if (unite(edge[i].u, edge[i].v))
		{
			if (ans < edge[i].w)ans = edge[i].w;
		}
	}
	printf("%lld", ans);


}


}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值