如果你 80 分且和之前的人挂的都不一样
查看原帖
如果你 80 分且和之前的人挂的都不一样
109114
_l_l_¯l¯l¯楼主2023/4/23 20:59

那么帮我调调把 /kel

#include <cstdio>
#include <algorithm>
#include <vector>
#include <array>
#include <stack>
using namespace std;
const int MAXN = 400005;
struct edge {
	int to, val, nxt;
} edges[MAXN * 10]; int tot; int tot11; int n;
int h1[MAXN], h11[MAXN << 1], h2[MAXN], hi[MAXN];
void add(int u, int v, int w, int *h) {
//	if (h == h11) printf("h11 %d %d %d\n", u, v, w);
//	if (h == hi) printf("hi %d %d %d\n", u, v, w);
	edges[++tot].to = v; edges[tot].val = w; edges[tot].nxt = h[u]; h[u] = tot;
}
void to3deg(int u, int f) {
	static vector<array<int, 2> > vc;
	for (int i = h1[u]; i; i = edges[i].nxt) {
		if (edges[i].to == f) continue; to3deg(edges[i].to, u);
	} vc.clear();
	for (int i = h1[u]; i; i = edges[i].nxt) {
		if (edges[i].to == f) continue; vc.push_back({edges[i].to, edges[i].val}); 
	}
	if (vc.empty()) return; int rt = u;
	for (int i = 0; i < (int)vc.size(); i++) {
		add(rt, vc[i][0], vc[i][1], h11); add(vc[i][0], rt, vc[i][1], h11);
		if (i < (int)vc.size() - 1) {
			add(rt, ++tot11, 0, h11); add(tot11, rt, 0, h11); rt = tot11;
		}
	}
}
long long dis11[MAXN << 1];
void prev11(int u, int f) {
	for (int i = h11[u]; i; i = edges[i].nxt) {
		if (edges[i].to != f) dis11[edges[i].to] = dis11[u] + edges[i].val, prev11(edges[i].to, u);
	}
}
long long dis2[MAXN]; int dfn2[MAXN], tm, fa2[MAXN][19], dep2[MAXN];
void prev2(int u, int f) {
	dfn2[u] = ++tm; fa2[u][0] = f; dep2[u] = dep2[f] + 1;
	for (int i = 1; i < 19; i++) fa2[u][i] = fa2[fa2[u][i - 1]][i - 1];
	for (int i = h2[u]; i; i = edges[i].nxt) {
		if (edges[i].to != f) dis2[edges[i].to] = dis2[u] + edges[i].val, prev2(edges[i].to, u);
	}
}
int lca2(int u, int v) {
	if (dep2[u] < dep2[v]) swap(u, v);
	for (int i = 18; ~i; i--) if (dep2[u] - (1 << i) >= dep2[v]) u = fa2[u][i];
	if (u == v) return u;
	for (int i = 18; ~i; i--) if (fa2[u][i] != fa2[v][i]) u = fa2[u][i], v = fa2[v][i];
	return fa2[u][0];
}
bool vis[MAXN << 1]; int nowG, siz[MAXN << 1]; vector<array<long long, 3> > vlst;
int coli[MAXN << 1]; long long datai[MAXN << 1]; long long dp[MAXN << 1][2];
long long ans = -1e18;
void Dp(int u, int f) {
//	printf("dp %d %d\n", u, f);
	dp[u][0] = dp[u][1] = -1e18; if (coli[u]) dp[u][coli[u] - 1] = datai[u];
	for (int i = hi[u]; i; i = edges[i].nxt) {
//		printf("%d %d %d ---\n", u, i, edges[i].to);
		if (edges[i].to == f) continue; Dp(edges[i].to, u);
		ans = max(ans, dp[u][0] + dp[edges[i].to][1] - 2 * dis2[u]);
		ans = max(ans, dp[u][1] + dp[edges[i].to][0] - 2 * dis2[u]);
		dp[u][0] = max(dp[u][0], dp[edges[i].to][0]);
		dp[u][1] = max(dp[u][1], dp[edges[i].to][1]);
	}
}
void solv() {
	int tmptot = tot; if (vlst.size() == 0) return;
	sort(vlst.begin(), vlst.end(), [&](array<long long, 3> &a, array<long long, 3> &b) {
		return dfn2[a[0]] < dfn2[b[0]];});
	for (int i = 0; i < (int)vlst.size(); i++) {
		hi[vlst[i][0]] = 0; coli[vlst[i][0]] = vlst[i][2]; datai[vlst[i][0]] = vlst[i][1];
	} hi[1] = 0; stack<int> stk({1});
	for (int i = vlst[0][0] == 1 ? 1 : 0; i < (int)vlst.size(); i++) {
		while (1) {
			int k = stk.top(); int lca = lca2(k, vlst[i][0]);
//			printf("%lld %d - %d\n", vlst[i][0], k, lca);
			if (lca == k) {stk.push(vlst[i][0]); break;} stk.pop();
			if (dep2[lca] > dep2[stk.top()]) {
				hi[lca] = 0; add(lca, k, 0, hi); stk.push(lca); stk.push(vlst[i][0]); break;
			}
			add(stk.top(), k, 0, hi);
		}
	}
	while (stk.size() > 1) {int k = stk.top(); stk.pop(); add(stk.top(), k, 0, hi);}
	Dp(1, 1);
	for (int i = 0; i < (int)vlst.size(); i++) coli[vlst[i][0]] = 0;
	tot = tmptot;
}
void findG(int u, int f, int sz) {
	siz[u] = 1; for (int i = h11[u]; i; i = edges[i].nxt) {
		if (edges[i].to == f || vis[edges[i].to]) continue; findG(edges[i].to, u, sz);
		siz[u] += siz[edges[i].to]; int v = edges[i].to;
		if (nowG == -1 ||
		max(siz[edges[nowG].to], sz - siz[edges[nowG].to]) > max(siz[v], sz - siz[v])) nowG = i;
	}
}
void inlst(int u, int f, long long dis, int id) {
//	printf("adl %d %lld %d\n", u, dis + dis11[u], id);
	if (u <= n) vlst.push_back({u, dis + dis11[u], id});
	for (int i = h11[u]; i; i = edges[i].nxt) {
		if (edges[i].to != f && vis[edges[i].to] == 0) inlst(edges[i].to, u, dis + edges[i].val, id);
	}
}
void dfz(int u) {
//	printf("%d\n", u);
	findG(u, u, 0); nowG = -1; findG(u, u, siz[u]); u = nowG; if (u == -1) return;
	vis[edges[u].to] = 1; vis[edges[u ^ 1].to] = 1;
	vlst.clear(); inlst(edges[u].to, 0, edges[u].val, 1); inlst(edges[u ^ 1].to, 0, 0, 2);
	solv(); dfz(edges[u].to); dfz(edges[u ^ 1].to);
}
int main() {
	tot = 1; scanf("%d", &n);
	for (int i = 1; i < n; i++) {
		int u, v, w; scanf("%d %d %d", &u, &v, &w); add(u, v, w, h1); add(v, u, w, h1);
	}
	for (int i = 1; i < n; i++) {
		int u, v, w; scanf("%d %d %d", &u, &v, &w); add(u, v, w, h2); add(v, u, w, h2);
	}
	tot11 = n; to3deg(1, 1); prev11(1, 1); prev2(1, 1); dfz(1); printf("%lld\n", max(ans, 0ll) / 2); return 0;
}
2023/4/23 20:59
加载中...