[codeforces1095F]Make It Connected

版权声明:辛辛苦苦码字,你们转载的时候记得告诉我 https://blog.csdn.net/dxyinme/article/details/91311440

time limit per test : 2 seconds
memory limit per test : 256 megabytes

You are given an undirected graph consisting of n n vertices. A number is written on each vertex; the number on vertex i i is a i a_i . 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 x x and y y is ax+ay coins. There are also m special offers, each of them is denoted by three numbers x x , y y and w w , and means that you can add an edge connecting vertices x x and y y and pay w coins for it. You don’t have to use special offers: if there is a pair of vertices x x and y y that has a special offer associated with it, you still may connect these two vertices paying a x + a y a_x+a_y 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 n n and m ( 1 n 2 1 0 5 , 0 m 2 1 0 5 ) m (1≤n≤2⋅10^5, 0≤m≤2⋅10^5) — the number of vertices in the graph and the number of special offers, respectively.

The second line contains n n integers a 1 , a 2 , , a n ( 1 a i 1 0 12 ) a_1,a_2,…,a_n (1≤a_i≤10^{12}) — the numbers written on the vertices.

Then m m lines follow, each containing three integers x x , y y and w ( 1 x , y n , 1 w 1 0 12 , x y ) w (1≤x,y≤n, 1≤w≤10^{12}, x≠y) denoting a special offer: you may add an edge connecting vertex x x and vertex y y , and this edge will cost w w coins.

Output

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

Examples
Input

3 2
1 3 3
2 3 5
2 1 1

Output

5

Input

4 0
1 3 3 7

Output

16

Input

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

Output

18

Note

In the first example it is possible to connect 1 to 2 using special offer 2, and then 1 to 3 without using any offers.

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

题意:
给定n个点,每个点有一个权值,连接两个点的花费是这两个点的权值和。还有m条特殊路径(x,y,w),表示连接点x和点y的花费可以是w。求问这n个点的最小生成树。

题解:
先考虑m=0的情况,我们可以发现只需要找到一个权值最小的点,然后其他点都直接跟它连接即可。
那么再考虑m>0的情况,我们只要找到跟最小权值点相连的n-1条边跟那m条边混在一起,然后直接kruskal即可。

#include<bits/stdc++.h>
#define LiangJiaJun main
#define ll long long
using namespace std;
struct edge{
    int u,v;
    ll w;
    edge(){}
    edge(int U,int V,ll W){
        u=U;v=V;w=W;
    }
}e[400004];
int f[200004];
int Find(int x){return f[x]==x?x:f[x]=Find(f[x]);}
int n,m;
ll a[200004];
inline bool dex(edge A,edge B){return A.w<B.w;}
int LiangJiaJun(){
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++){
        f[i]=i;
        scanf("%lld",&a[i]);
    }
    for(int i=1;i<=m;i++){
        scanf("%d%d%lld",&e[i].u,&e[i].v,&e[i].w);
    }
    int mint=1;
    for(int i=2;i<=n;i++){
        if(a[mint]>a[i])mint=i;
    }
    for(int i=1;i<=n;i++){
        if(mint!=i){
            e[++m]=edge(i,mint,a[i]+a[mint]);
        }
    }
    sort(e+1,e+m+1,dex);
    ll ans=0;
    for(int i=1;i<=m;i++){
        int p=Find(e[i].u),q=Find(e[i].v);
        if(p!=q){
            ans+=e[i].w;
            f[p]=q;
        }
    }
    printf("%lld\n",ans);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/dxyinme/article/details/91311440