修改

链接:https://ac.nowcoder.com/acm/contest/8564/I
来源:牛客网

题目描述
scimoon 有一个长度为 n 的数列

一个不幸的事实是,这个数列里的数非常地混乱,scimoon 想让它变得工整

scimoon 现在有 m 种操作,第 i 种操作可以把 [l_i,r_i][l
i

,r
i

] 之间的数全部加一或减一,但是,要使用它就必须先支付 w_iw
i

的费用,然后就可以无限制次数地使用这种操作

scimoon 想要知道,对于任意长度为 n 的数列,是否存在一种选择操作的方式,可以通过使用这些操作,使得所有数列中的数都等于 0

scimoon 并不富有,因此如果有解,他还想要知道最少支付多少费用
输入描述:
第一行两个整数 n,m,表示数列长度和操作个数

接下来 m 行,每行三个整数 l_i,r_i,w_il
i

,r
i

,w
i

,意义见题目描述
输出描述:
如果不存在一种选择操作的方式,输出 -1

否则输出最少支付的费用
示例1
输入
复制
2 3
1 2 3
1 1 100
2 2 101
输出
复制
103
示例2
输入
复制
5 4
1 1 1
2 2 1
3 3 1
4 4 1
输出
复制
-1
备注:

n\le 10^5,m\le 2\times 10^5n≤10
5
,m≤2×10
5

1\le l_i\le r_i\le n,1\le w_i\le 10^91≤l
i

≤r
i

≤n,1≤w
i

≤10
9

因为没有给定数组,所以要求任何一个数组都可以被修改为0,所以要求任何一个区间都可以被修改,设计区间修改,我们可以想到用差分,而差分·,而能修改所有的区间,所以差分需要可以连起来,题目说最小花费,暗示我们可以用最小生成树

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 1e5 + 10, M = 2e5 + 10;

int p[N];

struct Edge{
	int a, b;
	int w;
	bool operator<(const Edge &W)const{
		return w < W.w;
	}
}edge[M];

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

int main(){
	int n, m;
	scanf("%d%d", &n, &m);
	
	for (int i = 1; i <= m; i ++){
		int a, b, w;
		scanf("%d%d%d", &a, &b, &w);
		edge[i] = {a, b + 1, w};
	}
	
	sort(edge + 1, edge + 1 + m);
	
	for (int i = 1; i <= n; i ++)    p[i] = i;
	
	long long res = 0;
	int cnt = 0;
	for (int i = 1; i <= m; i ++){
		int a = edge[i].a, b = edge[i].b, w = edge[i].w;
		int pa = find(a), pb = find(b);
		
		if (pa != pb){
			p[pa] = pb;
			res += w;
			cnt ++;
		}
	}
	
	if (cnt != n)   cout << "-1" << endl;
	else cout << res << endl;
	
	return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值