Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- using namespace std;
- using int64 = long long;
- ifstream fin("trumplandia.in");
- ofstream fout("trumplandia.out");
- class edge {
- public:
- int u, v, w, ind;
- void read() {
- fin >> u >> v >> w;
- }
- bool operator < (const edge &A) const {
- return w < A.w;
- }
- };
- class DSU {
- public:
- int N;
- vector<int> p, r;
- DSU(int n) : N(n) {
- p.resize(N + 1);
- iota(p.begin(), p.end(), 0);
- r.assign(N + 1, 1);
- }
- int get(int x) {
- if(x == p[x])
- return x;
- return p[x] = get(p[x]);
- }
- bool unite(int u, int v) {
- int x = get(u),
- y = get(v);
- if(x == y)
- return false;
- if(r[x] > r[y]) {
- p[y] = x;
- r[x] += r[y];
- }
- else {
- p[x] = y;
- r[y] += r[x];
- }
- return true;
- }
- };
- class lca_node {
- public:
- int prv, mx;
- };
- const int NMAX = 2e5 + 2;
- int N, M, Q, lg2[NMAX], depth[NMAX];
- edge edges[NMAX];
- bool used[NMAX];
- int64 cost, sol[NMAX];
- vector<pair<int,int>> G[NMAX];
- lca_node ancestor[NMAX][19];
- void dfs(const int &u, const int &parent, const int &edge_value) {
- ancestor[u][0] = lca_node{parent, edge_value};
- for(int lift = 1; lift < 19; ++lift) {
- lca_node &p = ancestor[u][lift];
- lca_node half_ancestor = ancestor[u][lift - 1];
- p.prv = ancestor[half_ancestor.prv][lift - 1].prv;
- p.mx = max(half_ancestor.mx, ancestor[half_ancestor.prv][lift - 1].mx);
- }
- for(const pair<int,int> &v : G[u])
- if(v.first != parent) {
- depth[v.first] = depth[u] + 1;
- dfs(v.first, u, v.second);
- }
- }
- void max_self(int &a, int b) {
- a = max(a, b);
- }
- int query_max(int u, int v) {
- if(depth[u] < depth[v])
- swap(u, v);
- int ans = 0;
- for(int lift = 18; lift >= 0; --lift)
- if(depth[u] - (1 << lift) >= depth[v]) {
- lca_node node = ancestor[u][lift];
- max_self(ans, node.mx);
- u = node.prv;
- }
- if(u == v)
- return ans;
- for(int lift = 18; lift >= 0; --lift) {
- lca_node x = ancestor[u][lift], y = ancestor[v][lift];
- if(x.prv != y.prv) {
- max_self(ans, x.mx), max_self(ans, y.mx);
- u = x.prv, v = y.prv;
- }
- }
- return max({ans, ancestor[u][0].mx, ancestor[v][0].mx});
- }
- int main() {
- fin >> N >> M >> Q;
- for(int i = 1; i <= M; ++i) {
- edge &p = edges[i];
- p.read();
- p.ind = i;
- }
- sort(edges + 1, edges + M + 1);
- DSU tree(N);
- for(int i = 1; i <= M; ++i)
- if(tree.unite(edges[i].u, edges[i].v)) {
- edge e = edges[i];
- cost += e.w;
- used[e.ind] = true;
- G[e.u].emplace_back(e.v, e.w);
- G[e.v].emplace_back(e.u, e.w);
- }
- for(int i = 2; i <= N; ++i)
- lg2[i] = lg2[i >> 1] + 1;
- dfs(1, 0, 0);
- for(int i = 1; i <= M; ++i) {
- edge e = edges[i];
- if(used[e.ind])
- sol[e.ind] = cost;
- else
- sol[e.ind] = cost + e.w - query_max(e.u, e.v);
- }
- fout << cost << '\n';
- for(int q = 0; q < Q; ++q) {
- int index;
- fin >> index;
- fout << sol[index] << '\n';
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement