问题 B: 花园

题目描述
小N经常去小T家的花园里散步,小T家的花园有N个长的⼀样的亭⼦和M条道路连接着亭⼦,但是小T的花园太过于乱了,小N作为⼀个路痴经常进去了之后找不到出来的路,⼀直在环里面绕圈。于是小N要让小T把其中的某些路种上向日葵,使得剩下的路不会出现环。
因为向日葵不⽅便种,⽽第i条路长Li,需要Li个向日葵去种,于是小T想知道他最少要种多少向日葵才能满⾜小N的要求呢?

输入
第⼀⾏两个整数N、M,表示花园的亭⼦数目和道路数目;
接下来M⾏,每⾏3个整数A,B,C,表示有⼀条连接着A和B的长度为C的道路。

输出
输出⼀⾏,⼀个整数,表示小T最少需要种的向日葵数目。

样例输入
复制样例数据
5 5
1 2 5
1 4 4
3 4 3
2 3 2
3 5 1
样例输出
2

就是给定一个有向图, 有环图, 然后让你去掉一些边之后,使无环,并且去掉的边和最小,,,正向做不出来, 反向就是选一些边生成一个树(最小生成树肯定无环) , 所以剩下的就是最优的,但是我们一般求的最小生成树就是权值最小, 那么剩下的肯定最大了,与题意不符合, 所以我们将每条边取成相反数, 此时求最小生成树, 然后剩下的边才是最小的, 用此时 的最小生成树权值加上之前的全部权值和,就是答案,sum + res (sum , 原来图的所有权值之和, res, 相反数构成的最小生成树, 最小权值, 负的最小,相加就是最小了)

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 2e5 + 10 ;
typedef long long ll ;
struct node
{
	int a , b , w ;
	bool operator <(const node &p) const 
	 {
	 	return w < p.w ;
	 }
}e[N];
int f[N] ;

int find(int x)
{
	return f[x] == x ? x : f[x] = find(f[x]) ;
}
int main()
{
	ll res = 0 , sum = 0 ;
	int n , m ; 
	scanf("%d%d", &n , &m) ;
	for(int i = 1 ;i <= m ;i ++)
	 scanf("%d%d%d" , &e[i].a , &e[i].b , &e[i].w) ,  sum += e[i].w , e[i].w = -e[i].w ;
	sort(e + 1 , e + m + 1) ;
	for(int i = 1 ;i <= n ;i ++) f[i] = i ;
	int cnt = 0 ;
	for(int i = 1 ;i <= m ;i ++)
	 {
	 	int a = e[i].a , b = e[i].b , w = e[i].w ;
	 	int fa = find(a) , fb = find(b) ;
		if(fa != fb)
		 {
		 	f[fa] = fb ;
		 	res += w ;
		 	++ cnt ;
			if(cnt == n - 1) break ;
		 } 
	 }
	 printf("%lld\n" , res + sum) ;
	return 0 ;
}
全部评论

相关推荐

不愿透露姓名的神秘牛友
04-22 18:57
点赞 评论 收藏
分享
AI牛可乐:哇塞,恭喜恭喜!48万的年薪,真是让人羡慕呀!看来你找到了一个超棒的工作,可以享受不卷的生活啦!🎉有没有什么求职秘诀想要分享给小牛牛呢?或者,想不想知道我是谁呢?😉(点击我的头像,我们可以私信聊聊哦~)
点赞 评论 收藏
分享
ALEX_BLX:虽然说聊天记录不可信,不过这个趋势确实如此但我觉得也要想到一点就是卷后端的人里真正有“料”的人又有多少,我说的这个料都不是说一定要到大佬那种级别,而是就一个正常的水平。即使是现在也有很多人是跟风转码的,2-3个月速成后端技术栈的人数不胜数,但今时不同往日没可能靠速成进大厂了。这种情况就跟考研一样,你能上考场就已经打败一半的人了
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客企业服务