Submission #146997

#TimeUsernameProblemLanguageResultExecution timeMemory
146997qkxwsmToll (APIO13_toll)C++14
0 / 100
28 ms28664 KiB
#include <bits/stdc++.h> using namespace std; template<class T, class U> void ckmin(T &a, U b) { if (a > b) a = b; } template<class T, class U> void ckmax(T &a, U b) { if (a < b) a = b; } #define MP make_pair #define PB push_back #define LB lower_bound #define UB upper_bound #define fi first #define se second #define FOR(i, a, b) for (auto i = (a); i < (b); i++) #define FORD(i, a, b) for (auto i = (a) - 1; i >= (b); i--) #define SZ(x) ((int) ((x).size())) #define ALL(x) (x).begin(), (x).end() #define MAXN 300013 typedef long long ll; typedef long double ld; typedef pair<int, int> pii; typedef pair<ll, ll> pll; typedef vector<int> vi; typedef vector<ll> vl; typedef vector<pii> vpi; typedef vector<pll> vpl; int N, M, K; vector<pair<ll, pii> > edges; vi edge[MAXN], edge1[MAXN]; ll arr[MAXN]; vi nodes; map<int, ll> cost[MAXN]; vpi cand; int dsu[MAXN]; bitset<MAXN> flag, take, imp; int parent[MAXN]; ll dp[MAXN], subtree[MAXN]; ll ans; int get(int u) { return (u == dsu[u] ? u : dsu[u] = get(dsu[u])); } bool merge(int u, int v) { u = get(u); v = get(v); if (u == v) return false; dsu[u] = v; return true; } void dfs(int u, int p) { subtree[u] = arr[u]; for (int v : edge1[u]) { if (v == p) continue; parent[v] = u; dfs(v, u); subtree[u] += subtree[v]; } return; } int32_t main() { ios_base::sync_with_stdio(0); cin.tie(0); cin >> N >> M >> K; flag[0] = true; FOR(i, 0, M) { int u, v; ll d; cin >> u >> v >> d; u--; v--; if (u > v) swap(u, v); edges.PB({d, {u, v}}); } FOR(i, 0, K) { int u, v; cin >> u >> v; u--; v--; cand.PB({u, v}); flag[u] = true; flag[v] = true; } FOR(i, 0, N) { cin >> arr[i]; dsu[i] = i; } sort(ALL(edges)); for (auto e : edges) { // cerr << "HI\n"; int u = e.se.fi, v = e.se.se; ll d = e.fi; if (merge(u, v)) { cost[u][v] = d; cost[v][u] = d; edge[u].PB(v); edge[v].PB(u); // cerr << u << ' ' << v << ' ' << cost[u][v] << endl; } } flag[0] = true; FOR(i, 0, N) dsu[i] = i; FOR(u, 0, N) { if (flag[u]) continue; for (int v : edge[u]) { if (flag[v]) continue; merge(u, v); } } FOR(i, 0, N) { if (get(i) == i) nodes.PB(i); else { arr[get(i)] += arr[i]; } } edges.clear(); FOR(u, 0, N) { for (int v : edge[u]) { if ((!flag[u] && !flag[v]) || u > v) continue; edges.PB({cost[u][v], {get(u), get(v)}}); } } sort(ALL(edges)); dfs(0, N); M = SZ(edges); parent[0] = N; FOR(i, 0, (1 << K)) { for (int x : nodes) { dsu[x] = x; edge1[x].clear(); dp[x] = 0; imp[x] = false; } FOR(j, 0, K) { if (!(i & (1 << j))) continue; int u = cand[j].fi, v = cand[j].se; merge(u, v); } FOR(j, 0, SZ(edges)) { int u = edges[j].se.fi, v = edges[j].se.se; take[j] = merge(u, v); } FOR(j, 0, K) { if (!(i & (1 << j))) continue; int u = cand[j].fi, v = cand[j].se; edge1[u].PB(v); edge1[v].PB(u); } FOR(j, 0, SZ(edges)) { if (!take[j]) continue; int u = edges[j].se.fi, v = edges[j].se.se; edge1[u].PB(v); edge1[v].PB(u); } dfs(0, N); FOR(j, 0, K) { if (!(i & (1 << j))) continue; int u = cand[j].fi, v = cand[j].se; if (v == parent[u]) continue; imp[v] = true; } FORD(j, SZ(edges), 0) { if (take[j]) continue; int u = edges[j].se.fi, v = edges[j].se.se; ll d = edges[j].fi; //everything on the path u...v gets capped to vi pu, pv; while(u != 0) { pu.PB(u); u = parent[u]; } while(v != 0) { pv.PB(v); v = parent[v]; } while(pu.back() == pv.back()) { pu.pop_back(); pv.pop_back(); } for (int x : pu) dp[x] = d; for (int x : pv) dp[x] = d; } ll res = 0; for (int x : nodes) { if (!imp[x]) continue; res += subtree[x] * dp[x]; } ckmax(ans, res); } cout << ans << '\n'; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...