Submission #707521

#TimeUsernameProblemLanguageResultExecution timeMemory
707521600MihneaToll (APIO13_toll)C++17
78 / 100
2549 ms22620 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 <bitset> #include <sstream> #include <chrono> #include <cstring> #include <numeric> using namespace std; #define int long long struct Dsu { vector<int> t, wha; bool spec; int n; void init(int nn) { spec = 0; wha.clear(); n = nn; t.clear(); t.resize(n); iota(t.begin(), t.end(), 0); } int root(int a) { if (!spec) { if (t[a] == a) { return a; } return t[a] = root(t[a]); } return wha[a]; } bool join(int a, int b) { a = root(a); b = root(b); if (a == b) { return 0; } t[b] = a; return 1; } int nrml() { 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--; 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--; spec.push_back({ a, b }); } for (auto& p : people) { cin >> p; } sort(edges.begin(), edges.end()); { 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); int nredgesinit = 0, nredges = 0; auto addedge = [&](int a, int b, int c) { nredges++; g[a].push_back({ b, c }); g[b].push_back({ a, c }); }; Dsu dsuinit; dsuinit.init(n); for (auto& edge : mereu) { dsuinit.join(edge.a, edge.b); 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; bool fail = 0; Dsu dsu; g.clear(); g.resize(y); 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) { 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); } if (isspec[a]) { valup[a] = min(valup[a], cost); } a = parof[a]; } } } 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); } 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...