#include <bits/stdc++.h> using namespace std; template <typename T> T load() { T r; cin >> r; return r; } template <typename T> vector<T> loadMany(int n) { vector<T> rs(n); generate(rs.begin(), rs.end(), &load<T>); return rs; } struct Graph { Graph(int n):edges(n){} void addEdge2(int a, int b, long long w){ addEdge1(a,b); addEdge1(b,a); edgeWeight(a,b) = w; } int size() const {return edges.size();} long long& edgeWeight(int a, int b){ return weights[edgeUID(a, b)]; } template <typename PreV, typename PostV, typename PreE, typename PostE, typename FailE> void DFS(int source, PreV prev, PostV postv, PreE pree, PostE poste, FailE faile) const { auto visited = vector<bool>(size(), false); implDFS(source, visited, prev, postv, pree, poste, faile); } private: template <typename PreV, typename PostV, typename PreE, typename PostE, typename FailE> void implDFS(int vertex, vector<bool>& visited, PreV prev, PostV postv, PreE pree, PostE poste, FailE faile) const { prev(vertex); for (auto kid : edges[vertex]) if (not visited[kid]) visited[kid] = true, pree(vertex, kid), implDFS(kid, visited, prev, postv, pree, poste, faile), poste(vertex, kid); else faile(vertex, kid); postv(vertex); } void addEdge1(int a, int b){edges[a].push_back(b);} long long edgeUID(int a, int b) { if (a > b) swap(a, b); return static_cast<long long>(a) * size() + b; } vector<vector<int>> edges; unordered_map<long long, long long> weights; }; Graph loadEdges(int n, int m) { auto graph = Graph(n); for (int i=0; i<m; ++i) { auto a = load<int>() - 1; auto b = load<int>() - 1; auto w = load<long long>(); graph.addEdge2(a, b, w); } return graph; } template <typename F1, typename F2> void doQueries(int q, F1 f1, F2 f2) { for (int i=0; i<q; ++i) { auto type = load<int>(); if (type == 1) { auto v = load<int>() - 1; auto dprim = load<long long>(); f1(v, dprim); } else { auto a = load<int>() - 1; auto b = load<int>() - 1; auto wprim = load<long long>(); f2(a, b, wprim); } } } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); auto n = load<int>(); auto q = load<int>(); auto profits = loadMany<long long>(n); auto graph = loadEdges(n, n-1); auto currentVertex = 0; auto brut = [&]() -> long long { auto currCost = 0ll; auto maxVertex = -1; auto maxResult = numeric_limits<long long>::min(); graph.DFS(currentVertex, [&](int pre){ auto thisResult = max(maxResult, profits[pre] - currCost); if (make_pair(maxResult, -maxVertex) < make_pair(thisResult, -pre) and pre != currentVertex) { maxResult = thisResult; maxVertex = pre; } }, [&](int){}, [&](int prea, int preb){ currCost += graph.edgeWeight(prea, preb); }, [&](int posta, int postb){ currCost -= graph.edgeWeight(posta, postb); }, [&](int,int){}); currentVertex = maxVertex; return maxVertex; }; doQueries(q, [&](int vertex, int newProfit){ profits[vertex] = newProfit; auto result = brut(); cout << (result+1) << ' '; }, [&](int vert1, int vert2, int newCost){ graph.edgeWeight(vert1, vert2) = newCost; auto result = brut(); cout << (result+1) << ' '; }); cout << '\n'; }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | #include <bits/stdc++.h> using namespace std; template <typename T> T load() { T r; cin >> r; return r; } template <typename T> vector<T> loadMany(int n) { vector<T> rs(n); generate(rs.begin(), rs.end(), &load<T>); return rs; } struct Graph { Graph(int n):edges(n){} void addEdge2(int a, int b, long long w){ addEdge1(a,b); addEdge1(b,a); edgeWeight(a,b) = w; } int size() const {return edges.size();} long long& edgeWeight(int a, int b){ return weights[edgeUID(a, b)]; } template <typename PreV, typename PostV, typename PreE, typename PostE, typename FailE> void DFS(int source, PreV prev, PostV postv, PreE pree, PostE poste, FailE faile) const { auto visited = vector<bool>(size(), false); implDFS(source, visited, prev, postv, pree, poste, faile); } private: template <typename PreV, typename PostV, typename PreE, typename PostE, typename FailE> void implDFS(int vertex, vector<bool>& visited, PreV prev, PostV postv, PreE pree, PostE poste, FailE faile) const { prev(vertex); for (auto kid : edges[vertex]) if (not visited[kid]) visited[kid] = true, pree(vertex, kid), implDFS(kid, visited, prev, postv, pree, poste, faile), poste(vertex, kid); else faile(vertex, kid); postv(vertex); } void addEdge1(int a, int b){edges[a].push_back(b);} long long edgeUID(int a, int b) { if (a > b) swap(a, b); return static_cast<long long>(a) * size() + b; } vector<vector<int>> edges; unordered_map<long long, long long> weights; }; Graph loadEdges(int n, int m) { auto graph = Graph(n); for (int i=0; i<m; ++i) { auto a = load<int>() - 1; auto b = load<int>() - 1; auto w = load<long long>(); graph.addEdge2(a, b, w); } return graph; } template <typename F1, typename F2> void doQueries(int q, F1 f1, F2 f2) { for (int i=0; i<q; ++i) { auto type = load<int>(); if (type == 1) { auto v = load<int>() - 1; auto dprim = load<long long>(); f1(v, dprim); } else { auto a = load<int>() - 1; auto b = load<int>() - 1; auto wprim = load<long long>(); f2(a, b, wprim); } } } int main() { ios::sync_with_stdio(false); cin.tie(nullptr); auto n = load<int>(); auto q = load<int>(); auto profits = loadMany<long long>(n); auto graph = loadEdges(n, n-1); auto currentVertex = 0; auto brut = [&]() -> long long { auto currCost = 0ll; auto maxVertex = -1; auto maxResult = numeric_limits<long long>::min(); graph.DFS(currentVertex, [&](int pre){ auto thisResult = max(maxResult, profits[pre] - currCost); if (make_pair(maxResult, -maxVertex) < make_pair(thisResult, -pre) and pre != currentVertex) { maxResult = thisResult; maxVertex = pre; } }, [&](int){}, [&](int prea, int preb){ currCost += graph.edgeWeight(prea, preb); }, [&](int posta, int postb){ currCost -= graph.edgeWeight(posta, postb); }, [&](int,int){}); currentVertex = maxVertex; return maxVertex; }; doQueries(q, [&](int vertex, int newProfit){ profits[vertex] = newProfit; auto result = brut(); cout << (result+1) << ' '; }, [&](int vert1, int vert2, int newCost){ graph.edgeWeight(vert1, vert2) = newCost; auto result = brut(); cout << (result+1) << ' '; }); cout << '\n'; } |