Submission #707516

#TimeUsernameProblemLanguageResultExecution timeMemory
707516600MihneaToll (APIO13_toll)C++17
78 / 100
2545 ms31424 KiB
#include <cmath> #include <functional> #include <fstream> #include <iostream> #include <vector> #include <algorithm> #include <string> #include <set> #include <map> #include <list> #include <time.h> #include <math.h> #include <random> #include <deque> #include <queue> #include <unordered_map> #include <unordered_set> #include <iomanip> #include <cassert> #include <bitset> #include <sstream> #include <chrono> #include <cstring> #include <numeric> using namespace std; #define int long long struct Dsu { vector<int> t, h, wha; bool spec; int n; void init(int nn) { spec = 0; wha.clear(); n = nn; t.clear(); h.clear(); t.resize(n); h.resize(n, 0); iota(t.begin(), t.end(), 0); } int root(int a) { if (!spec) { while (t[a] != a) { a = t[a]; } return a; } return wha[a]; } bool join(int a, int b) { assert(!spec); a = root(a); b = root(b); if (a == b) { return 0; } if (h[a] < h[b]) { swap(a, b); } assert(h[a] >= h[b]); t[b] = a; h[a] += (h[a] == h[b]); return 1; } int nrml() { assert(!spec); wha.resize(n); map<int, int> mp; mp.clear(); for (int i = 0; i < n; i++) { mp[root(i)] = 0; } int y = 0; for (auto& it : mp) { it.second = y++; } for (int i = 0; i < n; i++) { wha[i] = mp[root(i)]; } spec = 1; return y; } }; struct Edge { int a; int b; int cost; }; bool operator < (Edge fi, Edge sc) { return fi.cost < sc.cost; } signed main() { #ifdef ONPC FILE* stream; freopen_s(&stream, "input.txt", "r", stdin); #else ios::sync_with_stdio(0); cin.tie(0); cout.tie(0); #endif int n, m, k; cin >> n >> m >> k; vector<int> people(n); vector<Edge> edges, newEdges; for (int i = 1; i <= m; i++) { int a, b, cost; cin >> a >> b >> cost; a--; b--; assert(0 <= a && a < n); assert(0 <= b && b < n); edges.push_back({ a, b, cost }); } vector<pair<int, int>> spec; for (int i = 1; i <= k; i++) { int a, b; cin >> a >> b; a--; b--; assert(0 <= a && a < n); assert(0 <= b && b < n); spec.push_back({ a, b }); } for (auto& p : people) { cin >> p; } sort(edges.begin(), edges.end()); assert((int)edges.size() == m); assert((int)spec.size() == k); { Dsu dsu; dsu.init(n); for (auto& edge : edges) { if (dsu.join(edge.a, edge.b)) { newEdges.push_back(edge); } } edges = newEdges; } vector<Edge> mereu, poate; { Dsu dsu; dsu.init(n); for (int i = 0; i < k; i++) { dsu.join(spec[i].first, spec[i].second); } for (auto& edge : edges) { if (!dsu.join(edge.a, edge.b)) { poate.push_back(edge); } else { mereu.push_back(edge); } } } vector<vector<pair<int, int>>> g(n); vector<pair<int, int>> now; int nredgesinit = 0, nredges = 0; auto addedge = [&](int a, int b, int c) { nredges++; assert(0 <= a && a < n); assert(0 <= b && b < n); g[a].push_back({ b, c }); g[b].push_back({ a, c }); now.push_back({ a, b }); }; Dsu dsuinit; dsuinit.init(n); for (auto& edge : mereu) { bool ok = dsuinit.join(edge.a, edge.b); assert(ok); addedge(edge.a, edge.b, edge.cost); } int y = dsuinit.nrml(); nredgesinit = nredges; vector<int> su(n, 0); for (int i = 0; i < n; i++) { su[dsuinit.root(i)] += people[i]; } for (int i = 0; i < n; i++) { g[i].clear(); } int sol = -1; for (int mask = 0; mask < (1 << k); mask++) { vector<int> inds; for (int bit = 0; bit < k; bit++) { if (mask & (1 << bit)) { inds.push_back(bit); } } nredges = nredgesinit; now.clear(); bool fail = 0; Dsu dsu; dsu.init(y); for (auto& i : inds) { if (!dsu.join(dsuinit.root(spec[i].first), dsuinit.root(spec[i].second))) { fail = 1; break; } addedge(dsuinit.root(spec[i].first), dsuinit.root(spec[i].second), (int)1e9 + 7); } if (fail) { for (auto& it : now) { assert(!g[it.first].empty()); assert(!g[it.second].empty()); g[it.first].pop_back(); g[it.second].pop_back(); } continue; } vector<Edge> reqs; for (auto& edge : poate) { if (dsu.join(dsuinit.root(edge.a), dsuinit.root(edge.b))) { addedge(dsuinit.root(edge.a), dsuinit.root(edge.b), edge.cost); } else { reqs.push_back({ dsuinit.root(edge.a), dsuinit.root(edge.b), edge.cost }); } } vector<int> parof(y), dep(y, 0), valup(y, 0), isspec(y, 0); { function<void(int, int)> build = [&](int a, int par) { parof[a] = par; for (auto& it : g[a]) { int b = it.first, c = it.second; if (b == par) { continue; } if (c == (int)1e9 + 7) { isspec[b] = 1; } valup[b] = c; dep[b] = 1 + dep[a]; build(b, a); } }; build(dsuinit.root(0), -1); for (auto& req : reqs) { int a = req.a, b = req.b, cost = req.cost; while (a != b) { if (dep[a] < dep[b]) { swap(a, b); } assert(dep[a] >= dep[b]); if (isspec[a]) { valup[a] = min(valup[a], cost); } a = parof[a]; } } } assert(nredges == n - 1); vector<int> sub(y, 0); int cur = 0; function<void(int, int)> build = [&](int a, int par) { parof[a] = par; sub[a] = su[a]; for (auto& it : g[a]) { int b = it.first; if (b == par) { continue; } build(b, a); sub[a] += sub[b]; if (isspec[b]) { cur += sub[b] * valup[b]; } } }; build(dsuinit.root(0), -1); sol = max(sol, cur); for (auto& it : now) { assert(!g[it.first].empty()); assert(!g[it.second].empty()); g[it.first].pop_back(); g[it.second].pop_back(); } } cout << sol << "\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...