1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
| #include<bits/stdc++.h> #include<bits/extc++.h> using namespace std; using namespace __gnu_pbds; inline void read(int &x){ char c = getchar(); int p = 1; x = 0; while(!isdigit(c)){ if(c == '-')p = -1; c = getchar(); } while(isdigit(c)){ x = (x << 1) + (x << 3) + (c ^ '0'); c = getchar(); } x *= p; } const int maxn = 200050, maxm = 500050; struct edge{ int u, v, w; }e[maxm]; #define mp make_pair tree<pair<int, int>, null_type, less<pair<int, int> >, rb_tree_tag, tree_order_statistics_node_update>se[maxn]; tree<pair<int, int>, null_type, less<pair<int, int> >, rb_tree_tag, tree_order_statistics_node_update>::iterator it; int c[maxn], n, m, l, f[maxn], cnt; long long ans; inline void init(){ for(register int i = 0; i <= n + 1; ++i){ f[i] = i; } } inline int getf(int u){ return f[u] == u ? u : f[u] = getf(f[u]); } inline void merg(int u, int v){ f[u] = v; } inline bool cmp(edge a, edge b){ return a.w < b.w; } int main(){ freopen("graph.in", "r", stdin); freopen("graph.out", "w", stdout); read(n), read(m), read(l); init(); for(register int i = 1; i <= n; ++i){ read(c[i]); se[i].insert(mp(c[i], ++cnt)); } for(register int i = 1; i <= m; ++i){ read(e[i].u), read(e[i].v), read(e[i].w); } sort(e + 1, e + 1 + m, cmp); int fu, fv, szu, szv, dis1, dis2; for(register int i = 1; i <= m; ++i){ fu = getf(e[i].u), fv = getf(e[i].v); if(fu != fv){ szu = se[fu].size(); szv = se[fv].size(); if(szu > szv)swap(fu, fv), swap(szu, szv); for(it = se[fu].begin(); it != se[fu].end(); ++it){ int val = (*it).first + l; dis1 = se[fv].order_of_key(mp(val - 1, ++cnt)); dis1 = szv - dis1; if(dis1 > 0)ans += 1ll * e[i].w * dis1; val = (*it).first - l; dis2 = se[fv].order_of_key(mp(val, ++cnt)); if(dis1 + dis2 > szv && l == 0){ dis2 = szv - dis1; } if(dis2 > 0)ans += 1ll * e[i].w * dis2; } for(it = se[fu].begin(); it != se[fu].end(); ++it){ se[fv].insert(mp((*it).first, ++cnt)); } se[fu].clear(); merg(fu, fv); } } printf("%lld\n", ans); return 0; }
|