Codeforces Round #529 (Div. 3) F. Make It Connected(最小生成樹)
阿新 • • 發佈:2018-12-28
AC
- 最小生成樹,建邊的時候不需要 ,首先N個點需要N-1條邊,每個頂點都會用到,也會有一些頂點重複。我們讓重複的點為權值最小的點,就可以保證生成樹最小
- 將特殊邊加到邊集裡,跑一邊Kruskal
#include <bits/stdc++.h>
#define P pair<int, int>
#define lowbit(x) (x & -x)
#define mem(a, b) memset(a, b, sizeof(a))
#define REP(i, n) for (int i = 1; i <= (n); ++i)
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define N 200006
#define LL long long
using namespace std;
struct ac{
LL u, v, d;
}g[N*2];
LL a[N];
int fa[N];
int find(int x) {
return x == fa[x] ? x : fa[x] = find(fa[x]);
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
#endif
int n, m;
while (scanf("%d %d", &n, &m) != EOF) {
int pos = 1;
REP (i, n) {
scanf ("%lld", &a[i]);
if (a[i] < a[pos]) pos = i;
}
int len = 0;
REP (i, n) {
if (i == pos) continue;
g[len].u = pos;
g[len].v = i;
g[len].d = a[pos] + a[i];
len++;
}
rep (i, m) {
scanf("%lld %lld %lld", &g[len].u, &g[len].v, &g[len].d);
++len;
}
sort(g, g + len, [&](const ac &x, const ac &y){
return x.d < y.d;
});
REP (i, n) fa[i] = i;
LL u, v, d, ans = 0, cnt = 0;
rep (i, len) {
u = g[i].u;
v = g[i].v;
d = g[i].d;
if (find(u) != find(v)) {
fa[find(u)] = find(v);
ans += d;
if (++cnt == n-1) break;
}
}
printf("%lld\n", ans);
}
return 0;
}