Submission #586985

#TimeUsernameProblemLanguageResultExecution timeMemory
5869858e7Reconstruction Project (JOI22_reconstruction)C++17
42 / 100
5104 ms217820 KiB
//Challenge: Accepted #include <bits/stdc++.h> #pragma GCC optimize("Ofast") using namespace std; #ifdef zisk void debug(){cout << endl;} template<class T, class ... U> void debug(T a, U ... b){cout << a << " ", debug(b...);} template<class T> void pary(T l, T r) { while (l != r) cout << *l << " ", l++; cout << endl; } #else #define debug(...) 0 #define pary(...) 0 #endif #define ll long long #define maxn 505 #define pii pair<int, int> #define ff first #define ss second #define io ios_base::sync_with_stdio(0);cin.tie(0); const int inf = 1<<30; struct edge{ int u, v, w; edge(){u = v = w = 0;} edge(int a, int b, int c){u = a, v = b, w = c;} }; inline void del(vector<pii> &v, pii x) { v.erase(find(v.begin(), v.end(), x)); } inline void del(vector<int> &v, int x) { v.erase(find(v.begin(), v.end(), x)); } struct graph{ vector<int> ed; //first < second vector<pii> adj[maxn]; pii best; int bid, t; void init(int n) { ed.clear(); t = 0; for (int i = 0;i <= n;i++) adj[i].clear(); } bool getpath(int n, int par, int goal) { if (n == goal) return 1; for (auto [v, id]:adj[n]) { if (v != par && getpath(v, n, goal)) { if (id < bid) { bid = id; best = {n, v}; } return 1; } } return 0; } void upd(int u, int v) { bid = inf; t++; if (u > v) swap(u, v); if (getpath(u, 0, v)) { if (best.ff > best.ss) swap(best.ff, best.ss); del(adj[best.ff], make_pair(best.ss, bid)); del(adj[best.ss], make_pair(best.ff, bid)); del(ed, bid); } adj[u].push_back({v, t}); adj[v].push_back({u, t}); ed.push_back(t); } } g; vector<int> tree[100005]; struct DSU{ int par[maxn]; void init(int n) { for (int i = 1;i <= n;i++) par[i] = i; } int find(int a) { return a == par[a] ? a : (par[a] = find(par[a])); } bool Union(int a, int b) { a = find(a), b = find(b); if (a == b) return 0; par[a] = b; return 1; } } dsu; int main() { io int n, m; cin >> n >> m; vector<edge> ed; for (int i = 0;i < m;i++) { int u, v, w; cin >> u >> v >> w; ed.push_back(edge(u, v, w)); } sort(ed.begin(), ed.end(), [&] (edge x, edge y){return x.w < y.w;}); int q; cin >> q; vector<int> que(q); for (int i = 0;i < q;i++) { cin >> que[i]; } //for (int i = m - 1;i >= 0;i--) debug(ed[i].u, ed[i].v, ed[i].w); g.init(n); for (int i = m - 1;i >= 0;i--) { g.upd(ed[i].u, ed[i].v); tree[i] = g.ed; } g.init(n); int ind = 0; auto answer = [&] (int L, int id) { while (ind < q && que[ind] < L) { ll ans = 0; vector<int> &lef = g.ed, &rig = tree[id]; dsu.init(n); int p = (int)rig.size() - 1; auto addedge = [&] (edge &e) { if (dsu.Union(e.u, e.v)) ans += abs(e.w - que[ind]); }; for (int i = (int)lef.size()-1;i >= 0;i--) { while (p >= 0 && abs(ed[m-rig[p]].w-que[ind]) < abs(ed[lef[i]-1].w-que[ind])) { addedge(ed[m-rig[p]]); p--; } addedge(ed[lef[i]-1]); } while (p >= 0) { addedge(ed[m-rig[p]]); p--; } cout << ans << "\n"; ind++; } }; for (int i = 0;i < m;i++) { answer(ed[i].w, i); g.upd(ed[i].u, ed[i].v); } answer(inf, m); }
#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...
#Verdict Execution timeMemoryGrader output
Fetching results...