Submission #1194076

#TimeUsernameProblemLanguageResultExecution timeMemory
1194076_callmelucianToll (APIO13_toll)C++17
56 / 100
165 ms12428 KiB
#include <bits/stdc++.h> using namespace std; using ll = long long; using ld = long double; using pl = pair<ll,ll>; using pii = pair<int,int>; using tpl = tuple<int,int,int>; #define all(a) a.begin(), a.end() #define filter(a) a.erase(unique(all(a)), a.end()) struct DSU { vector<int> lab, weight; DSU (int sz) : lab(sz + 1, -1), weight(sz + 1) {} int get (int u) { if (lab[u] < 0) return u; return lab[u] = get(lab[u]); } int getWeight (int u) { return weight[get(u)]; } void asgn (int u, int cur) { weight[get(u)] = cur; } bool unite (int a, int b) { a = get(a), b = get(b); if (a == b) return 0; if (-lab[a] < -lab[b]) swap(a, b); lab[a] += lab[b], weight[a] += weight[b]; return lab[b] = a, 1; } }; const int mn = 1e5 + 5; ll cmpr[mn], cmp[mn], edw[mn], sumWeight[mn]; ll dp[mn], par[mn], depth[mn]; vector<pii> adj[mn]; void dfs (int u, int p, int d) { dp[u] = sumWeight[u], par[u] = p, depth[u] = d; for (auto [v, w] : adj[u]) { if (v == p) continue; dfs(v, u, d + 1); edw[v] = w, dp[u] += dp[v]; } } void process (int u, int v, ll cur) { while (u != v) { if (depth[u] == depth[v]) { edw[u] = min(edw[u], cur), u = par[u]; edw[v] = min(edw[v], cur), v = par[v]; } else if (depth[u] > depth[v]) edw[u] = min(edw[u], cur), u = par[u]; else if (depth[v] > depth[u]) edw[v] = min(edw[v], cur), v = par[v]; } } int main() { // freopen("TOLL.inp", "r", stdin); // freopen("TOLL.out", "w", stdout); ios::sync_with_stdio(0); cin.tie(0); /// read input int n, m, k; cin >> n >> m >> k; vector<tpl> edge(m), unused; vector<pii> newEdge(k), used; DSU init(n), dsu(n); for (int i = 0; i < m; i++) { int a, b, c; cin >> a >> b >> c; edge[i] = make_tuple(c, a, b); } for (int i = 0; i < k; i++) { int a, b; cin >> a >> b; newEdge[i] = make_pair(a, b); init.unite(a, b); } sort(all(edge)); for (int i = 1; i <= n; i++) { int w; cin >> w; dsu.asgn(i, w); } /// classify edges for (auto [c, a, b] : edge) { if (init.unite(a, b)) used.emplace_back(a, b); else unused.emplace_back(c, a, b); } init = DSU(n), edge.clear(); for (auto [a, b] : used) init.unite(a, b), dsu.unite(a, b); for (auto [c, a, b] : unused) if (init.unite(a, b)) edge.emplace_back(c, a, b); /// re-index connected components int counter = 0; for (int i = 1; i <= n; i++) if (i == dsu.get(i)) cmpr[i] = ++counter, sumWeight[counter] = dsu.getWeight(i); for (int i = 1; i <= n; i++) cmp[i] = cmpr[dsu.get(i)]; /// try all subsets of new edges ll ans = 0; for (int mask = 0; mask < (1 << k); mask++) { // process chosen edges dsu = DSU(counter); bool flag = 1; for (int i = 0; i < k; i++) { if (mask & (1 << i)) continue; int a, b; tie(a, b) = newEdge[i]; a = cmp[a], b = cmp[b]; if (dsu.unite(a, b)) { adj[a].emplace_back(b, INT_MAX); adj[b].emplace_back(a, INT_MAX); } else { flag = 0; break; } } if (flag) { // form 1 component for (auto [c, a, b] : edge) { int u = cmp[a], v = cmp[b]; if (dsu.unite(u, v)) { adj[u].emplace_back(v, 0); adj[v].emplace_back(u, 0); } } // dfs & set edge weight dfs(cmp[1], 0, 0); for (auto [c, a, b] : edge) process(cmp[a], cmp[b], c); ll curCost = 0; for (int i = 1; i <= counter; i++) curCost += 1LL * edw[i] * dp[i]; ans = max(ans, curCost); } // clear data for (int i = 1; i <= counter; i++) adj[i].clear(); } cout << ans; 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...