如题,思路是正难则反,离线,先把所有边都删掉,然后倒过来合并
#include <bits/stdc++.h>
#define F(i, a, b) for(int i = (a); i <= (b); ++i)
#define dF(i, a, b) for(int i = (a); i >= (b); --i)
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
typedef unsigned int uint;
const int N = 1e5 + 5;
const LL K = 1e10;
int tot, rt;
struct node { int ls, rs, siz; } t[N * 50];
void Update(LL x, int k, LL l, LL r, int &u) {
if (!u) u = ++tot; t[u].siz += k;
if (l != r) { LL mid = l + r >> 1;
if (x <= mid) Update(x, k, l, mid, t[u].ls);
else Update(x, k, mid + 1, r, t[u].rs);
}
} LL Query(LL l, LL r, int u) {
if (l == r) return l; LL mid = l + r >> 1;
if (t[t[u].rs].siz) return Query(mid + 1, r, t[u].rs);
else return Query(l, mid, t[u].ls);
}
int _, n, q, u[N], v[N], w[N], op[N]; bool b[N];
struct edge { int v, w; } ; vector<edge> e[N], g[N];
LL dis[N]; int cnt, dfn[N], dep[N], st[18][N];
void Dfs(int u, int f) {
dep[u] = dep[st[0][dfn[u] = ++cnt] = f] + 1;
for (auto it : e[u]) if (it.v != f)
dis[it.v] = dis[u] + it.w, Dfs(it.v, u);
} int Get(int x, int y) { return dep[x] < dep[y] ? x : y; }
int Lca(int u, int v) {
if (u == v) return u; if (dfn[u] > dfn[v]) swap(u, v);
int k = log2(dfn[v] - dfn[u]); return Get(st[k][dfn[u] + 1], st[k][dfn[v] - (1 << k) + 1]);
} LL Dis(int u, int v) { return dis[u] + dis[v] - 2 * dis[Lca(u, v)]; }
LL dist[N]; int far;
void Getdis(int u, int f) {
if (dist[u] > dist[far]) far = u;
for (auto it : g[u]) if (it.v != f)
dist[it.v] = dist[u] + it.w, Getdis(it.v, u);
}
int fa[N], be[N], ed[N]; LL mx[N], ans[N]; bool vis[N];
int Find(int x) { return fa[x] == x ? x : fa[x] = Find(fa[x]); }
int main() {
freopen("wmyr.in", "r", stdin);
freopen("wmyr.out", "w", stdout);
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cin >> _; while (_--) {
cin >> n >> q; F(i, 1, n - 1)
cin >> u[i] >> v[i] >> w[i],
e[u[i]].push_back({v[i], w[i]}), e[v[i]].push_back({u[i], w[i]});
Dfs(1, 0); F(i, 1, 17) for (int j = 1; j + (1 << i) - 1 <= n; ++j)
st[i][j] = Get(st[i - 1][j], st[i - 1][j + (1 << i - 1)]);
F(i, 1, q) cin >> op[i], b[op[i]] = 1;
F(i, 1, n) fa[i] = i;
F(i, 1, n - 1) if (!b[i])
g[u[i]].push_back({v[i], w[i]}), g[v[i]].push_back({u[i], w[i]}),
fa[Find(u[i])] = Find(v[i]);
F(i, 1, n) if (!vis[Find(i)]) {
int u = Find(i); vis[u] = 1;
dist[far = 0] = -1, dist[u] = 0, Getdis(u, 0), be[u] = far;
dist[far = 0] = -1, dist[be[u]] = 0, Getdis(be[u], 0), ed[u] = far, far = 0;
Update(mx[u] = dist[ed[u]], 1, 1, K, rt);
} dF(i, q, 1) {
ans[i] = Query(1, K, rt);
int x = Find(u[op[i]]), y = Find(v[op[i]]);
Update(mx[x], -1, 1, K, rt), Update(mx[y], -1, 1, K, rt);
LL d1 = Dis(be[x], be[y]), d2 = Dis(be[x], ed[y]);
LL d3 = Dis(ed[x], be[y]), d4 = Dis(ed[x], ed[y]);
mx[fa[x] = y] = max(max(max(d1, d2), max(d3, d4)), max(mx[x], mx[y]));
Update(mx[y], 1, 1, K, rt);
if (mx[y] == d1) ed[y] = be[x];
else if (mx[y] == d2) be[y] = be[x];
else if (mx[y] == d3) ed[y] = ed[x];
else if (mx[y] == d4) be[y] = ed[x];
else if (mx[y] == mx[x]) be[y] = be[x], ed[y] = ed[x];
} F(i, 1, q) cout << ans[i] << "\n";
F(i, 1, tot) t[i].ls = t[i].rs = t[i].siz = 0; tot = cnt = rt = 0;
F(i, 1, n) b[i] = vis[i] = 0, e[i].clear(), g[i].clear();
}
return 0;
}