洛谷 P2121

该博客探讨了一种图论问题,即如何从给定的边中选择最多k条,使得图中任意两点间路径唯一且权值和最大化。文章介绍了最大生成树的概念,并指出只需将最小生成树的排序策略反转即可解决此问题。提供的C++代码实现了这一算法,通过并查集维护图的联通状态,最终输出最大权值之和。
摘要由CSDN通过智能技术生成

题目链接

题目大意

从原先给出的m条边中选出最多k条边,使得任意可到达两点之间的路径只有一条,最后要使整个图的权值和最大。

最小生成树 (懂的大佬请自行跳过)

我们先来看看什么是最小生成树。
最小生成树是一颗任意两个节点之间只有一条路径,并且整棵树的权值和最小的一颗树。

区别

我们这道题是求整个图的最大值,所以我们只要把它当作一棵最大生成树就好了,只需要修改最小生成树的排序方式就好了。

上代码!!!
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<map>
#define ll long long
#define pi acos(-1)
#define inf 0x3f3f3f3f
#define pii pair<int, int>
#define fi first
#define se second
#define mp(a, b) make_pair(a, b)
#define piii pair<pii, int>
#define uf(a, b, i) for (register int i = (a); i <= (b); ++i)
#define df(a, b, i) for (register int i = (a); i >= (b); --i)
using namespace std;
inline int read() {
	int x = 0, f = 1;
	char ch = getchar();
	while(ch < '0' || ch > '9') {
		if(ch == '-') f = -1;
		ch = getchar();
	}
	while(ch >= '0' && ch <= '9') {
		x = x * 10 + ch - '0';
		ch = getchar();
	}
	return x * f;
}
template<class T>
inline void print(T x) {
	if(x > 9) print(x/10);
	putchar(x%10 + '0');
}
template<class T>
T Max(T a, T b) {
  return a > b ? a : b;
}
template<class T>
T Min(T a, T b) {
  return a < b ? a : b;
}
const ll mod = 1e9 + 7;
struct edg{
  int u, v, w;
  bool operator < (const edg &e1) {
    return w > e1.w;
  }
} e[100005];
int n, m, k; 
ll ans;
int f[100005];
int find(int x) {
  return f[x] == x ? x : (f[x] = find(f[x]));
}
void scan() {
  n = read(); m = read(); k = read();
  uf(1, m, i) {
    e[i].u = read(); e[i].v = read(); e[i].w = read();
  }
}
void work() {
  sort(e+1, e+m+1);
  uf(1, n, i) f[i] = i;
  uf(1, m, i) {
    int fu = find(e[i].u), fv = find(e[i].v);
    if (fu != fv) {
      f[fu] = fv;
      ans += e[i].w;
      --k;
    }
    if (!k) break;
  }
  print(ans);
  putchar('\n');
}
int main() {
	scan();
	work();
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值