RT,用的是点分治+虚树上dp的做法,但40分有 WA 有 T,求巨佬把WA改好就行。
code:
#include <bits/stdc++.h>
using namespace std;
using LL = long long;
using Pii = pair<int, int>;
const int kMaxN = 366667, kL = 21;
int dep[kMaxN], f[kL][kMaxN], id[kMaxN << 2], dfn[kMaxN], dp[kMaxN][2], tot, n, m, cnt; // 基础,虚树
int vis[kMaxN], p[kMaxN << 2], pos[kMaxN], s[kMaxN], fv[kMaxN], sz, rt; // 点分治,重心
LL val[kMaxN], dis[kMaxN], dist[kMaxN]; // 在原树上的值,dis:T2,dist:T1
LL c[kMaxN], ans = -1e18; // 在虚树上的dis,color,原树上的dis
vector<Pii> g[3][kMaxN];
// Lca begin
void InitLen(int u, int fa) {
for (Pii i : g[0][u]) {
if (i.first != fa) {
dist[i.first] = dist[u] + i.second;
InitLen(i.first, u);
}
}
}
void InitDfs(int u, int fa) {
dep[u] = dep[fa] + 1, dfn[u] = ++cnt;
pos[u] = tot + 1;
for (Pii i : g[1][u]) {
if (i.first != fa) {
id[++tot] = u, dis[i.first] = dis[u] + i.second;
InitDfs(i.first, u);
}
}
id[++tot] = u;
}
int Min(int x, int y) {
return dep[x] <= dep[y] ? x : y;
}
int Lca(int x, int y) {
int l = pos[x], r = pos[y];
(l > r) && (swap(l, r), 1);
int v = p[r - l + 1];
return Min(f[v][l], f[v][r - (1 << v) + 1]);
}
void Init() {
p[0] = -1;
for (int i = 1; i <= tot; i++) {
p[i] = p[i >> 1] + 1;
}
for (int i = 1; i <= tot; i++) {
f[0][i] = id[i];
}
for (int i = 1; i < kL; i++) {
for (int j = 1; j + (1 << i) - 1 <= tot; j++) {
f[i][j] = Min(f[i - 1][j], f[i - 1][j + (1 << i - 1)]);
}
}
}
// 虚树begin
bool Cmp(int x, int y) {
return dfn[x] < dfn[y];
}
LL Dis(int x, int y) {
int l = Lca(x, y);
return dis[x] + dis[y] - 2 * dis[l];
}
void Add(int u, int v) {
if (u != v) {
g[2][u].push_back({v, 0}), g[2][v].push_back({u, 0});
}
}
void Build() {
int v = cnt;
id[++v] = 1;
for (int i = 1; i < cnt; i++) {
id[++v] = Lca(id[i], id[i + 1]);
}
cnt = v;
sort(id + 1, id + cnt + 1, Cmp);
cnt = unique(id + 1, id + cnt + 1) - id - 1;
if (cnt == 1) {
g[2][id[1]].clear();
dp[id[1]][0] = dp[id[1]][1] = 0;
return;
}
for (int i = 1; i <= cnt; i++) {
g[2][id[i]].clear(), dp[id[i]][0] = dp[id[i]][1] = 0;
(i < cnt) && (g[2][Lca(id[i], id[i + 1])].clear(), 1);
}
Add(Lca(id[1], id[2]), id[1]);
for (int i = 1; i < cnt; i++) {
Add(Lca(id[i], id[i + 1]), id[i + 1]);
}
}
// dpdp!!!!!!!
bool GetMax(int x, int y) {
return val[x] > val[y];
}
void Dp(int u, int fa) {
c[u] && (dp[u][0] = u);
(c[u] == -1) && (ans = max(ans, val[u] * 2 - dis[u] * 2));
for (Pii i : g[2][u]) {
int v = i.first;
if (v != fa) {
Dp(v, u);
for (int j = 0; j < 2; j++) {
for (int k = 0; k < 2; k++) {
if (dp[u][j] && dp[v][k] && c[dp[u][j]] != c[dp[v][k]]) {
// cout << val[dp[u][j]] + val[dp[v][k]] - 2 * dis[u] << " " << dp[u][j] << " " << dis[u] << " " << u << "\n";
ans = max(ans, val[dp[u][j]] + val[dp[v][k]] - 2 * dis[u]);
}
}
}
int a[] = {dp[u][0], dp[u][1], dp[v][0], dp[v][1]};
sort(a, a + 4, GetMax);
dp[u][0] = a[0];
for (int i = 1; i < 4; i++) {
if (c[a[i]] != c[a[0]]) {
dp[u][1] = a[i];
break;
}
}
}
}
}
// 找重心
void FindRt(int u, int fa) {
fv[u] = 0, s[u] = 1;
for (Pii i : g[0][u]) {
if (i.first != fa && !vis[i.first]) {
FindRt(i.first, u);
fv[u] = max(fv[u], s[i.first]);
s[u] += s[i.first];
}
}
fv[u] = max(fv[u], sz - s[u]);
(fv[u] <= fv[rt]) && (rt = u);
}
// 点分治
void Clear(int u, int fa) {
c[u] = 0;
for (Pii i : g[0][u]) {
if (i.first != fa) {
Clear(i.first, u);
}
}
}
void Dfs(int u, int fa, int col, LL dis) {
c[u] = col, id[++cnt] = u;
val[u] = dis + dist[u];
for (Pii i : g[0][u]) {
if (i.first != fa && !vis[i.first]) {
Dfs(i.first, u, col, dis + i.second);
}
}
}
void Work(int u) {
cnt = 0, val[u] = dist[u];
for (Pii i : g[0][u]) {
if (!vis[i.first]) {
Dfs(i.first, u, i.first, i.second);
}
}
id[++cnt] = u, c[u] = -1;
Build();
Dp(1, 0);
// cout << u << " ------------------\n";
c[u] = 0;
for (Pii i : g[0][u]) {
if (!vis[i.first]) {
Clear(i.first, u);
}
}
}
void Solve(int u) {
vis[u] = 1;
Work(u);
for (Pii i : g[0][u]) {
if (!vis[i.first]) {
rt = 0, sz = s[i.first];
FindRt(i.first, u);
Solve(rt);
}
}
}
int main() {
// freopen("wronganswer7.in", "r", stdin);
ios ::sync_with_stdio(0), cin.tie(0), cout.tie(0);
fv[0] = 1e9;
cin >> n;
for (int id = 0; id < 2; id++) {
for (int i = 1, u, v, w; i < n; i++) {
cin >> u >> v >> w;
g[id][u].push_back({v, w}), g[id][v].push_back({u, w});
}
}
InitLen(1, 0);
InitDfs(1, 0);
Init();
cnt = 0;
sz = n, rt = 0;
FindRt(1, 0);
Solve(rt);
cout << ans / 2;
return 0;
}