牛客练习赛69 C

题意: 给定 n n n m m m边,让你确定一个大小为 n n n的排列使得 ∑ i = 2 n d i s ( a i − 1 , a i ) \sum_{i=2}^n dis(a_{i-1},a_i) i=2ndis(ai1,ai)最大。
数据范围: 1 ≤ m ≤ 5 × 1 0 5 , 1 ≤ u , v ≤ n , 1 ≤ w ≤ 1 0 9 1\leq m\leq 5\times 10^5, 1\leq u,v\leq n, 1\leq w\leq 10^9 1m5×105,1u,vn,1w109,保证图是联通的

题解: 本题考虑一个问题,即要想求图中两点的所有路径中的最大值,那么我们在选择排列的时候,就从边权最大的开始递减构造,将这两个点放一块,那么这两个点就一定是选择边权当前可选择的最大值了。这里就想到了生成树,构造一个最大生成树即可。

题解:

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

const int N = 5e5 + 10;
const int M = N << 1;
int n, m;

struct Node{
	int a, b, c;
	bool operator < (const Node &A) const {
		return c > A.c;
	}
}p[N];

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

int main()
{
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= n; i++) f[i] = i;
	for(int i = 1; i <= m; i++) {
		int a, b, c;
		scanf("%d%d%d", &a, &b, &c);
		p[i] = {a, b, c};
	} 
	
	sort(p + 1, p + m + 1);
	long long res = 0;
	for(int i = 1; i <= m; i++) {
		int a = p[i].a, b = p[i].b, c = p[i].c;
		a = find(a), b = find(b);
		if(a != b) {
			f[a] = b;
			res += c;
		}
	}
	
	printf("%lld\n", res);
	
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值