Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <bits/stdc++.h>
- #define all(x) begin(x), end(x)
- using namespace std;
- using ll = long long;
- void InitIO(string name = "") {
- ios_base::sync_with_stdio(false);
- cin.tie(nullptr);
- cout.tie(nullptr);
- if (name.size()) {
- freopen((name + ".in").c_str(), "r", stdin);
- freopen((name + ".out").c_str(), "w", stdout);
- }
- }
- struct Edge {
- int to, w;
- };
- const int N = 1e5 + 1;
- const int LOG = 18;
- void Dfs(int from, int par, int d, vector<vector<Edge>>& g, vector<int>& depth) {
- depth[from] = d;
- for (auto& [to, w] : g[from]) {
- if (to == par) continue;
- Dfs(to, from, d + w, g, depth);
- }
- }
- void Dfs2(int from, int p, vector<vector<int>>& par, vector<int>& depth, vector<vector<Edge>>& g) {
- par[from].assign(LOG, p);
- for (int i = 1; i < LOG; i++) {
- par[from][i] = par[par[from][i - 1]][i - 1];
- }
- for (auto& [to, w] : g[from]) {
- if (to == p) continue;
- depth[to] = depth[from] + w;
- Dfs2(to, from, par, depth, g);
- }
- }
- pair<vector<vector<int>>, vector<int>> make_lca(int from, int n, vector<vector<Edge>>& g) {
- vector<vector<int>> par(n, vector<int>(LOG));
- vector<int> depth(n);
- Dfs2(from, from, par, depth, g);
- return {par, depth};
- }
- int Lca(int a, int b, vector<vector<int>>& par, vector<int>& depth) {
- if (depth[a] < depth[b]) swap(a, b);
- for (int i = LOG - 1; i >= 0; i--) {
- if (depth[par[a][i]] >= depth[b]) {
- a = par[a][i];
- }
- }
- if (a == b) return a;
- for (int i = LOG - 1; i >= 0; i--) {
- if (par[a][i] != par[b][i]) {
- a = par[a][i];
- b = par[b][i];
- }
- }
- return par[a][0];
- }
- int Dist(int a, int b, vector<vector<int>>& par, vector<int>& depth) {
- int c = Lca(a, b, par, depth);
- return depth[a] + depth[b] - 2 * depth[c];
- }
- int Get(int a, int h, vector<vector<int>>& par, vector<int>& depth) {
- // root, x, a, dist(a,x) <= h
- int x = a;
- for (int i = LOG - 1; i >= 0; i--) {
- if (depth[a] - depth[par[x][i]] <= h) {
- x = par[x][i];
- }
- }
- return x;
- }
- void Dfs3(int from, int par, vector<vector<Edge>>& graph, vector<vector<Edge>>& graph_next) {
- for (auto& [to, w] : graph[from]) {
- if (to == par) {
- graph_next[par].push_back({from, w});
- } else {
- Dfs3(to, from, graph, graph_next);
- }
- }
- }
- vector<vector<Edge>> make_graph(int from, int n, vector<vector<Edge>>& graph) {
- vector<vector<Edge>> g(n);
- Dfs3(from, from, graph, g);
- return g;
- }
- int Solve(int v, int n, vector<vector<Edge>>& graph_start) {
- auto graph = make_graph(v, n, graph_start);
- auto [par, d] = make_lca(v, n, graph);
- vector<int> leaves;
- for (int i = 0; i < n; i++) {
- if (graph[i].size() == 0u) {
- leaves.push_back(i);
- }
- }
- int left = 0;
- int right = 1e9;
- int mid;
- int ans = 1e9;
- while (left <= right) {
- mid = (left + right) >> 1;
- vector<pair<int,int>> arr = {{0, v}};
- for (int leaf : leaves) {
- int cur = Get(leaf, mid, par, d);
- arr.emplace_back(d[cur], cur);
- }
- int mx = arr[0].second;
- int mx_val = 0;
- for (int i = 0; i < int(arr.size()); i++) {
- if (arr[i].first > mx_val) {
- mx = arr[i].second;
- mx_val = arr[i].first;
- }
- }
- //for (auto& [d, c] : arr) {
- // cout << "d c " << d << ' ' << c << '\n';
- //}
- int A = mx;
- int B = mx;
- mx_val = 0;
- for (int i = 0; i < int(arr.size()); i++) {
- int cur_dist = Dist(arr[i].second, A, par, d);
- if (cur_dist > mx_val) {
- mx_val = cur_dist;
- B = arr[i].second;
- }
- }
- //cout << "mid " << mid << " v " << v + 1 << " A B " << A + 1 << " " << B + 1 << '\n';
- bool good = true;
- int tot = Dist(A, B, par, d);
- //cout << "Tot dist " << tot << '\n';
- /*
- 4
- 1 2 10000
- 1 3 10000
- 1 4 10000
- */
- for (int i = 0; i < int(arr.size()) && good; i++) {
- int C = arr[i].second;
- good &= Dist(A, C, par, d) + Dist(C, B, par, d) == tot;
- }
- if (good) {
- ans = mid;
- right = mid - 1;
- } else {
- left = mid + 1;
- }
- //cout << (good ? "True" : "False") << '\n';
- }
- return ans;
- }
- int main() {
- InitIO();
- int n;
- cin >> n;
- vector<vector<Edge>> g(n);
- vector<int> depth(n);
- for (int i = 0; i < n - 1; i++) {
- int f, t, w;
- cin >> f >> t >> w;
- f--, t--;
- g[f].push_back({t, w});
- g[t].push_back({f, w});
- }
- Dfs(0, 0, 0, g, depth);
- int a = max_element(all(depth)) - begin(depth);
- Dfs(a, a, 0, g, depth);
- int b = max_element(all(depth)) - begin(depth);
- int ans = depth[b];
- auto [par, d] = make_lca(a, n, g);
- int first = Get(b, (ans + 1) / 2, par, d);
- int second = par[first][0];
- for (int v : vector<int>{first, second}) {
- ans = min(ans, Solve(v, n, g));
- }
- cout << ans << '\n';
- }
Add Comment
Please, Sign In to add comment