Submission #147017

#TimeUsernameProblemLanguageResultExecution timeMemory
147017qkxwsmToll (APIO13_toll)C++14
0 / 100
98 ms86264 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 ord, nodes; map<int, ll> cost[MAXN], weight[MAXN]; vpi cand; int dsu[MAXN]; bitset<MAXN> flag, take, imp; int parent[MAXN], depth[MAXN]; ll dp[MAXN], subtree[MAXN]; pii bound[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 dfs1(int u, int p) { subtree[u] = arr[u]; ord.PB(u); for (int v : edge[u]) { if (v == p) continue; parent[v] = u; depth[v] = depth[u] + 1; dfs1(v, u); ord.PB(u); subtree[u] += subtree[v]; } } void dfs(int u, int p) { subtree[u] = weight[u][u]; for (int v : edge1[u]) { if (v == p) continue; parent[v] = u; dfs(v, u); subtree[u] += subtree[v]; subtree[u] += weight[u][v]; } return; } void mark(int u) { //lower, upper if (flag[u]) bound[u].se = u; for (int v : edge[u]) { if (v == parent[u]) continue; bound[v].se = bound[u].se; mark(v); bound[u].fi = bound[v].fi; } if (flag[u]) bound[u].fi = u; } 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; } flag[0] = 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; } } parent[0] = N; dfs1(0, N); int best = 0; for (int u : ord) { if (flag[u]) { if (nodes.empty() || best != nodes.back()) nodes.PB(best); if (nodes.empty() || u != nodes.back()) nodes.PB(u); best = u; continue; } if (depth[u] > depth[best]) best = u; } for (int u : nodes) flag[u] = true; FOR(i, 0, SZ(nodes) - 1) { int u = nodes[i], v = nodes[i + 1]; if (depth[v] < depth[u]) swap(u, v); ll len = 0, wei = 0; while(v != u) { assert(v != N); wei += arr[v]; ckmax(len, cost[v][parent[v]]); v = parent[v]; } edges.PB({len, {u, v}}); } sort(ALL(edges)); FOR(i, 0, N) bound[i] = {-1, -1}; mark(0); FOR(i, 0, N) if (bound[i].fi == -1) bound[i].fi = bound[i].se; FOR(i, 0, N) { weight[bound[i].fi][bound[i].se] += arr[i]; if (bound[i].fi != bound[i].se) weight[bound[i].se][bound[i].fi] += arr[i]; } parent[0] = N; sort(ALL(nodes)); nodes.erase(unique(ALL(nodes)), nodes.end()); FOR(i, 0, (1 << K)) { // cerr << "SOLVE " << i << endl; 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); // cerr << u << " -> " << v << endl; } 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); // cerr << u << " -> " << v << endl; } 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]) swap(u, v); 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.empty() && !pv.empty() && 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; // cerr << "ADD " << x << endl; res += subtree[x] * dp[x]; } ckmax(ans, res); // cerr << "RES " << res << endl; } 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...