Submission #1165297

#TimeUsernameProblemLanguageResultExecution timeMemory
1165297KerimToll (APIO13_toll)C++20
100 / 100
875 ms11264 KiB
#include "bits/stdc++.h" #define ll long long #define ff first #define ss second #define edgew tuple<int, int, int> #define edge pair<int,int> using namespace std; struct connectivity{ vector<int> ata; vector<int> sz; int n; connectivity(int _n){ n = _n; ata.resize(n+1); sz.resize(n+1); } void init(){ for (int i = 1; i <= n; i++) ata[i] = i, sz[i] = 1; } int tap(int x){ if (ata[x] == x) return x; return ata[x] = tap(ata[x]); } bool merge(int x, int y){ if ((x=tap(x)) == (y=tap(y))) return 0; if (sz[x] < sz[y]) swap(x, y); ata[y] = x; sz[x] += sz[y]; return 1; } bool is_connected(int x, int y){ return tap(x) == tap(y); } vector<int> get_components(){ vector<int> components; for (int i = 1; i <= n; i++) if (ata[i] == i) components.push_back(i); return components; } }; const int N = 1e5+5; const int K = 20; const int INF = 1e9; edge blue_edges[K]; ll a[N]; vector<int> adj[N]; void add_edge(int u, int v){ adj[u].push_back(v); adj[v].push_back(u); } ll sub[N]; int par[N], lvl[N], l[N]; void dfs(int nd, int pr){ par[nd] = pr; sub[nd] = a[nd]; for (auto to: adj[nd]) if (to != pr){ lvl[to] = lvl[nd]+1; dfs(to, nd); sub[nd] += sub[to]; } } void upd(int u, int v, int w){ while (u != v){ if (lvl[u] > lvl[v]) swap(u, v); l[v] = min(l[v], w); v = par[v]; } } int n, m, k, root = 1; vector<edgew> simplify(vector<edgew> edges){ assert(edges.size() <= n-1); connectivity dsu(n); dsu.init(); for (int i = 0; i < k; i++){ auto [u, v] = blue_edges[i]; dsu.merge(u, v); } vector<bool> essential(edges.size(), 0); for (int i = 0; i < edges.size(); i++){ auto [w, u, v] = edges[i]; essential[i] = dsu.merge(u, v); } dsu.init(); for (int i = 0; i < edges.size(); i++){ auto [w, u, v] = edges[i]; if (essential[i]) dsu.merge(u, v); } vector<int> id(n+1); vector<int> roots = dsu.get_components(); int np = 0; for (int i = 0; i < roots.size(); i++) id[roots[i]] = ++np; vector<edgew> nedges; for (int i = 0; i < edges.size(); i++){ auto [w, u, v] = edges[i]; if (!essential[i]) nedges.push_back({w, id[dsu.tap(u)], id[dsu.tap(v)]}); } for (int i = 0; i < k; i++){ auto &[u, v] = blue_edges[i]; u = id[dsu.tap(u)]; v = id[dsu.tap(v)]; } vector<ll> na(np+1); for (int i = 1; i <= n; i++) na[id[dsu.tap(i)]] += a[i]; n = np; for (int i = 1; i <= n; i++) a[i] = na[i]; root = id[dsu.tap(root)]; assert(nedges.size() <= k); return nedges; } int main(){ // freopen("file.in", "r", stdin); scanf("%d%d%d", &n, &m, &k); vector<edgew> black_edges(m); for (int i = 0; i < m; i++){ int u, v, w; scanf("%d%d%d", &u, &v, &w); black_edges[i] = {w, u, v}; } sort(black_edges.begin(), black_edges.end()); connectivity dsu(n); dsu.init(); // black edges vector<edgew> selected; for (int i = 0; i < m; i++){ auto [w, u, v] = black_edges[i]; if (dsu.merge(u, v)) selected.push_back(black_edges[i]); } for (int i = 0; i < k; i++){ int u, v; scanf("%d%d", &u, &v); blue_edges[i] = {u, v}; } for (int i = 1; i <= n; i++) scanf("%lld", a+i); selected = simplify(selected); assert(n <= k+1); ll ans = 0; connectivity ndsu(n); for (int mask = 0; mask < (1<<k); mask++){ ndsu.init(); for (int i = 1; i <= n; i++) adj[i].clear(), l[i] = INF; bool valid = true; for (int i = 0; i < k; i++) if (mask>>i&1){ auto [u, v] = blue_edges[i]; add_edge(u, v); if (!ndsu.merge(u, v)) valid = false; } if (!valid) continue; vector<bool> state(selected.size(), 0); for (int i = 0; i < selected.size(); i++){ auto [w, u, v] = selected[i]; state[i] = ndsu.merge(u, v); if (state[i]) add_edge(u, v); } dfs(root, -1); for (int i = 0; i < selected.size(); i++){ auto [w, u, v] = selected[i]; if (!state[i]) upd(u, v, w); } ll value = 0; for (int i = 0; i < k; i++) if (mask>>i&1){ auto [u, v] = blue_edges[i]; add_edge(u, v); if (lvl[u] > lvl[v]) swap(u, v); value += l[v] * sub[v]; } ans = max(ans, value); } printf("%lld\n", ans); }

Compilation message (stderr)

toll.cpp: In function 'int main()':
toll.cpp:133:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  133 |         scanf("%d%d%d", &n, &m, &k);
      |         ~~~~~^~~~~~~~~~~~~~~~~~~~~~
toll.cpp:137:22: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  137 |                 scanf("%d%d%d", &u, &v, &w);
      |                 ~~~~~^~~~~~~~~~~~~~~~~~~~~~
toll.cpp:152:22: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  152 |                 scanf("%d%d", &u, &v);
      |                 ~~~~~^~~~~~~~~~~~~~~~
toll.cpp:156:22: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  156 |                 scanf("%lld", a+i);
      |                 ~~~~~^~~~~~~~~~~~~
#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...