[ABC210E] Ring MST 题解

链接

洛谷相应链接

atcoder 相应链接

题意

n ( 1 ≤ n ≤ 1 0 9 ) n(1 \leq n \leq 10^9) n(1n109) 个点的图,并给长度为 m ( 1 ≤ m ≤ 1 0 5 ) m(1 \leq m \leq 10^5) m(1m105) 的两个数组 a , b ( 1 ≤ a i ≤ n − 1 , 1 ≤ b i ≤ 1 0 9 ) a,b(1 \leq a_i \leq n - 1,1 \leq b_i \leq 10^9) a,b(1ain1,1bi109)

每次可选择在点 x ( 1 ≤ x ≤ n ) x(1\leq x\leq n) x(1xn) ( x + a i ) m o d    n (x + a_i)\mod n (x+ai)modn 中添加一个长度为 b i b_i bi 的边,问添加的边的长度总和至少为多少,才能使得整个图连通,不连通输出 -1

思路

考虑 m = 1 m = 1 m=1 时,如果要建成联通图,必须要让 gcd ⁡ ( n , a 1 ) = 1 \gcd(n,a_1) = 1 gcd(n,a1)=1,否则会发生如下情况:
在这里插入图片描述
如果 m > 1 m > 1 m>1 则同理可得当 gcd ⁡ ( n , a 1 , a 2 ⋯ a m ) = 1 \gcd(n,a_1,a_2\cdots a_m) = 1 gcd(n,a1,a2am)=1 时有解。这样我们已经解决了判断无解的情况。

对于任意一个 i i i,可知最多可将剩下的 p p p 个点合并成剩下 gcd ⁡ ( p , a i ) \gcd(p,a_i) gcd(p,ai) 个点,我们先按照 b i b_i bi 大小排序,对于每一次操作连通块的数量都由 p ← gcd ⁡ ( p , a i ) p \gets \gcd(p,a_i) pgcd(p,ai),则 a n s ← a n s + ( p − gcd ⁡ ( p , a i ) ) × b i ans \gets ans + (p - \gcd(p,a_i)) \times b_i ansans+(pgcd(p,ai))×bi。若有解,最后输出 a n s ans ans 即可。

代码

#include<bits/stdc++.h>
#define int long long
using namespace std;
int n,m;
int gcd(int x,int y) {
	return y?gcd(y,x % y):x;
}
struct edge{
	int a,b;
	friend bool operator <(edge x,edge y) {
		return x.b < y.b;
	}
}node[200005];
int ans = 0;
signed main() {
	cin >> n >> m;
	for(int i = 1;i <= m;i++) cin >> node[i].a >> node[i].b;
	sort(node + 1,node + m + 1);
	for(int i = 1;i <= m;i++) {
		ans += (n - gcd(n,node[i].a)) * node[i].b;
		n = gcd(n,node[i].a);
		if(n <= 1) {
			cout<<ans<<endl;
			return 0;
		}
	}
	cout<<"-1"<<endl;
	return 0;
}

  • 13
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值