999ms

Untitled

Sep 21st, 2020 (edited)
269
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.55 KB | None | 0 0
  1. #include <bits/stdc++.h>
  2. #define all(x) begin(x), end(x)
  3.  
  4. using namespace std;
  5. using ll = long long;
  6.  
  7. void InitIO(string name = "") {
  8.     ios_base::sync_with_stdio(false);
  9.     cin.tie(nullptr);
  10.     cout.tie(nullptr);
  11.     if (name.size()) {
  12.         freopen((name + ".in").c_str(), "r", stdin);
  13.         freopen((name + ".out").c_str(), "w", stdout);
  14.     }
  15. }
  16.  
  17. struct Edge {
  18.     int to, w;
  19. };
  20.  
  21. const int N = 1e5 + 1;
  22. const int LOG = 18;
  23.  
  24.  
  25. void Dfs(int from, int par, int d, vector<vector<Edge>>& g, vector<int>& depth) {
  26.     depth[from] = d;
  27.     for (auto& [to, w] : g[from]) {
  28.         if (to == par) continue;
  29.         Dfs(to, from, d + w, g, depth);
  30.     }
  31. }
  32.  
  33. void Dfs2(int from, int p, vector<vector<int>>& par, vector<int>& depth, vector<vector<Edge>>& g) {
  34.     par[from].assign(LOG, p);
  35.     for (int i = 1; i < LOG; i++) {
  36.         par[from][i] = par[par[from][i - 1]][i - 1];
  37.     }
  38.     for (auto& [to, w] : g[from]) {
  39.         if (to == p) continue;
  40.         depth[to] = depth[from] + w;
  41.         Dfs2(to, from, par, depth, g);
  42.     }
  43. }
  44.  
  45.  
  46. pair<vector<vector<int>>, vector<int>> make_lca(int from, int n, vector<vector<Edge>>& g) {
  47.     vector<vector<int>> par(n, vector<int>(LOG));
  48.     vector<int> depth(n);
  49.     Dfs2(from, from, par, depth, g);
  50.     return {par, depth};
  51. }
  52.  
  53. int Lca(int a, int b, vector<vector<int>>& par, vector<int>& depth) {
  54.     if (depth[a] < depth[b]) swap(a, b);
  55.     for (int i = LOG - 1; i >= 0; i--) {
  56.         if (depth[par[a][i]] >= depth[b]) {
  57.             a = par[a][i];
  58.         }
  59.     }
  60.     if (a == b) return a;
  61.     for (int i = LOG - 1; i >= 0; i--) {
  62.         if (par[a][i] != par[b][i]) {
  63.             a = par[a][i];
  64.             b = par[b][i];
  65.         }
  66.     }
  67.     return par[a][0];
  68. }
  69.  
  70. int Dist(int a, int b, vector<vector<int>>& par, vector<int>& depth) {
  71.     int c = Lca(a, b, par, depth);
  72.     return depth[a] + depth[b] - 2 * depth[c];
  73. }
  74.  
  75. int Get(int a, int h, vector<vector<int>>& par, vector<int>& depth) {
  76.     // root, x, a, dist(a,x) <= h
  77.     int x = a;
  78.     for (int i = LOG - 1; i >= 0; i--) {
  79.         if (depth[a] - depth[par[x][i]] <= h) {
  80.             x = par[x][i];
  81.         }
  82.     }
  83.     return x;
  84. }
  85.  
  86. void Dfs3(int from, int par, vector<vector<Edge>>& graph, vector<vector<Edge>>& graph_next) {
  87.     for (auto& [to, w] : graph[from]) {
  88.         if (to == par) {
  89.             graph_next[par].push_back({from, w});
  90.         } else {
  91.             Dfs3(to, from, graph, graph_next);
  92.         }
  93.     }
  94. }
  95.  
  96. vector<vector<Edge>> make_graph(int from, int n, vector<vector<Edge>>& graph) {
  97.     vector<vector<Edge>> g(n);
  98.     Dfs3(from, from, graph, g);
  99.     return g;
  100. }
  101.  
  102. int Solve(int v, int n, vector<vector<Edge>>& graph_start) {
  103.     auto graph = make_graph(v, n, graph_start);
  104.     auto [par, d] = make_lca(v, n, graph);
  105.     vector<int> leaves;
  106.     for (int i = 0; i < n; i++) {
  107.         if (graph[i].size() == 0u) {
  108.             leaves.push_back(i);
  109.         }
  110.     }
  111.     int left = 0;
  112.     int right = 1e9;
  113.     int mid;
  114.     int ans = 1e9;
  115.     while (left <= right) {
  116.         mid = (left + right) >> 1;
  117.         vector<pair<int,int>> arr = {{0, v}};
  118.         for (int leaf : leaves) {
  119.             int cur = Get(leaf, mid, par, d);
  120.             arr.emplace_back(d[cur], cur);
  121.         }      
  122.         int mx = arr[0].second;
  123.         int mx_val = 0;
  124.         for (int i = 0; i < int(arr.size()); i++) {
  125.             if (arr[i].first > mx_val) {
  126.                 mx = arr[i].second;
  127.                 mx_val = arr[i].first;
  128.             }
  129.         }
  130.         //for (auto& [d, c] : arr) {
  131.         //  cout << "d c " << d << ' ' << c << '\n';
  132.         //}
  133.         int A = mx;
  134.         int B = mx;
  135.         mx_val = 0;
  136.         for (int i = 0; i < int(arr.size()); i++) {
  137.             int cur_dist = Dist(arr[i].second, A, par, d);
  138.             if (cur_dist > mx_val) {
  139.                 mx_val = cur_dist;
  140.                 B = arr[i].second;
  141.             }
  142.         }
  143.        
  144.         //cout << "mid " << mid << " v " << v + 1 << " A B " << A + 1 << " " << B + 1 << '\n';
  145.         bool good = true;
  146.         int tot = Dist(A, B, par, d);
  147.         //cout << "Tot dist " << tot << '\n';
  148. /*
  149. 4
  150. 1 2 10000
  151. 1 3 10000
  152. 1 4 10000
  153.     */ 
  154.         for (int i = 0; i < int(arr.size()) && good; i++) {
  155.             int C = arr[i].second;
  156.            
  157.             good &= Dist(A, C, par, d) + Dist(C, B, par, d) == tot;
  158.         }
  159.         if (good) {
  160.             ans = mid;
  161.             right = mid - 1;
  162.         } else {
  163.             left = mid + 1;
  164.         }
  165.         //cout << (good ? "True" : "False") << '\n';
  166.     }
  167.     return ans;
  168. }
  169.  
  170. int main() {
  171.     InitIO();
  172.     int n;
  173.     cin >> n;
  174.     vector<vector<Edge>> g(n);
  175.     vector<int> depth(n);
  176.     for (int i = 0; i < n - 1; i++) {
  177.         int f, t, w;
  178.         cin >> f >> t >> w;
  179.         f--, t--;
  180.         g[f].push_back({t, w});
  181.         g[t].push_back({f, w});
  182.     }
  183.     Dfs(0, 0, 0, g, depth);
  184.     int a = max_element(all(depth)) - begin(depth);
  185.     Dfs(a, a, 0, g, depth);
  186.     int b = max_element(all(depth)) - begin(depth);
  187.     int ans = depth[b];
  188.    
  189.     auto [par, d] = make_lca(a, n, g);
  190.     int first = Get(b, (ans + 1) / 2, par, d);
  191.     int second = par[first][0];
  192.     for (int v : vector<int>{first, second}) {
  193.         ans = min(ans, Solve(v, n, g));
  194.     }
  195.     cout << ans << '\n';
  196. }
  197.  
Add Comment
Please, Sign In to add comment