Codeforces Round #529 (Div. 3)F. Make It Connected 【最小生成树】

You are given an undirected graph consisting of nn vertices. A number is written on each vertex; the number on vertex ii is aiai. Initially there are no edges in the graph.

You may add some edges to this graph, but you have to pay for them. The cost of adding an edge between vertices xx and yy is ax+ayax+aycoins. There are also mm special offers, each of them is denoted by three numbers xx, yy and ww, and means that you can add an edge connecting vertices xx and yy and pay ww coins for it. You don't have to use special offers: if there is a pair of vertices xx and yy that has a special offer associated with it, you still may connect these two vertices paying ax+ayax+ay coins for it.

What is the minimum number of coins you have to spend to make the graph connected? Recall that a graph is connected if it's possible to get from any vertex to any other vertex using only the edges belonging to this graph.

Input

The first line contains two integers nn and mm (1≤n≤2⋅1051≤n≤2⋅105, 0≤m≤2⋅1050≤m≤2⋅105) — the number of vertices in the graph and the number of special offers, respectively.

The second line contains nn integers a1,a2,…,ana1,a2,…,an (1≤ai≤10121≤ai≤1012) — the numbers written on the vertices.

Then mm lines follow, each containing three integers xx, yy and ww (1≤x,y≤n1≤x,y≤n, 1≤w≤10121≤w≤1012, x≠yx≠y) denoting a special offer: you may add an edge connecting vertex xx and vertex yy, and this edge will cost ww coins.

Output

Print one integer — the minimum number of coins you have to pay to make the graph connected.

Examples

input

Copy

3 2
1 3 3
2 3 5
2 1 1

output

Copy

5

input

Copy

4 0
1 3 3 7

output

Copy

16

input

Copy

5 4
1 2 3 4 5
1 2 8
1 3 10
1 4 7
1 5 15

output

Copy

18

Note

In the first example it is possible to connect 11 to 22 using special offer 22, and then 11 to 33 without using any offers.

In next two examples the optimal answer may be achieved without using special offers.

#include<bits/stdc++.h>
using namespace std;
const int MAX = 2e5 + 7;
#define ll long long
struct node{
    ll x, y, z;
    bool operator < (const node &a) const{
        return z < a.z;
    }
};
ll aa[MAX];
int pre[MAX];
int findx(int x){
    return x == pre[x] ? x : pre[x] = findx(pre[x]);
}
int main(){
    int n, m;
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++){
        pre[i] = i;
    }
    int pos;
    ll mn = 1e12 + 100;
    for(int i = 1; i <= n; i++){
        scanf("%lld", &aa[i]);
        if(mn > aa[i]){
            mn = aa[i];
            pos = i;
        }
    }
    vector <node> v;
    for(int i = 1; i <= n; i++){
        if(i == pos) continue;
        v.push_back({i, pos, mn + aa[i]});
    }
    for(int i = 0; i < m; i++){
        ll x, y, z;
        scanf("%lld%lld%lld", &x, &y, &z);
        v.push_back({x, y, z});
    }
    sort(v.begin(), v.end());
    int k = n - 1;
    ll ans = 0;
    for(int i = 0; i < v.size(); i++){
        ll x = v[i].x;
        ll y = v[i].y;
        if(findx(x) != findx(y)){
            pre[findx(x)] = pre[findx(y)];
            ans += v[i].z;
            k--;
        }
        if(k == 0) break;
    }
    printf("%lld\n", ans);
    return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值