1. 程式人生 > >Codeforces Round #529 (Div. 3) F. Make It Connected(最小生成樹)

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

在這裡插入圖片描述

AC

  • 最小生成樹,建邊的時候不需要 N 2 {N^2} ,首先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; }