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 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132
| #pragma GCC optimize("O3") #include <bits/stdc++.h> using namespace std; #define inline inline __attribute__((always_inline)) __attribute__((optimize("O3"))) const int iol = 1024 * 1024; char buf[iol], *s1, *t, ioc; bool iosig; inline char read() { if (s1 == t) { t = (s1 = buf) + fread(buf, 1, iol, stdin); if (s1 == t) return -1; } return *s1++; } template<class T> inline bool read(T& x) { iosig = false; for (ioc = read(); !isdigit(ioc); ioc = read()) { if (ioc == -1) return false; if (ioc == '-') iosig = true; } x = 0; while (ioc == '0') ioc = read(); for (; isdigit(ioc); ioc = read()) x = (x << 1) + (x << 3) + (ioc ^ '0'); s1--; if (iosig) x = -x; return true; } const int MAX_N = 300000 + 3, MAX_M = 300000 + 3, INF = 0x3f3f3f3f; struct Node { int v, w; Node() {} Node(int v1, int w1) : v(v1), w(w1) {} }; vector<Node> pool[MAX_N * 2]; int n, m; int queryFrom[MAX_M], queryTo[MAX_M], queryCost[MAX_M], queryLca[MAX_M]; int depth[MAX_N], dis[MAX_N], fc[MAX_N], ancestor[20][MAX_N]; int dfsSeq[MAX_N], cnt = 0; inline void dfs() { stack<int> st; static bool vis[MAX_N]; memset(vis, 0, sizeof (bool) * n); st.push(0); ancestor[0][0] = -1, depth[0] = 0, dis[0] = 0; while (!st.empty()) { register int u = st.top(); if (!vis[u]) { for (register int i = 0; i < pool[u].size(); i++) { Node *e = &pool[u][i]; if (e->v != ancestor[0][u]) { depth[e->v] = depth[u] + 1; dis[e->v] = dis[u] + e->w; fc[e->v] = e->w; ancestor[0][e->v] = u; st.push(e->v); } } vis[u] = true; } else dfsSeq[cnt++] = st.top(), st.pop(); } } inline int lca(int a, int b) { if (depth[a] < depth[b]) swap(a, b); register int bits = 0, q = 1; while (depth[a] - q > 0) bits++, q <<= 1; for (int i = bits; i >= 0; --i) if (depth[a] - (1 << i) >= depth[b]) a = ancestor[i][a]; if (a == b) return a; for (register int i = bits; i >= 0; --i) if ((depth[a] - (1 << i) >= 0) && ancestor[i][a] != ancestor[i][b]) a = ancestor[i][a], b = ancestor[i][b]; return ancestor[0][a]; } inline void init() { dfs(); for (int w = 1; (1 << w) < n; ++w) for (int i = 0; i < n; ++i) if (depth[i] - (1 << w) >= 0) ancestor[w][i] = ancestor[w - 1][ancestor[w - 1][i]]; for (int i = 0; i < m; ++i) { int LCA = lca(queryFrom[i], queryTo[i]); queryCost[i] = dis[queryFrom[i]] + dis[queryTo[i]] - 2 * dis[LCA]; queryLca[i] = LCA; } } int s[MAX_N]; inline bool check(int t) { int total = 0, maxT = 0; memset(s, 0, sizeof (int) * n); for (int i = 0; i < m; ++i) { if (queryCost[i] <= t) continue; total++; s[queryFrom[i]]++, s[queryTo[i]]++, s[queryLca[i]] -= 2; maxT = max(maxT, queryCost[i] - t); } for (int i = 0, u; i < n; ++i) { u = dfsSeq[i]; s[ancestor[0][u]] += s[u]; } int dec = 0; for (int i = 0; i < n; ++i) if (s[i] == total) dec = max(dec, fc[i]); return maxT <= dec; } inline void solve() { int l = -1, r = 300000000; while (r - l > 1) { int mid = (l + r) >> 1; if (check(mid)) r = mid; else l = mid; } cout << r << "\n"; } int main() { #ifndef ONLINE_JUDGE freopen("in.in", "r", stdin); #endif read(n), read(m); for (register int i = 0, f, t, c; i < n - 1; ++i) { read(f), f--, read(t), t--, read(c); pool[f].push_back(Node(t, c)); pool[t].push_back(Node(f, c)); } for (register int i = 0; i < m; i++) read(queryFrom[i]), queryFrom[i]--, read(queryTo[i]), queryTo[i]--; init(); solve(); return 0; }
|