虚树模板

[SDOI2011] 消耗战

\(\text{Code}\)

#include <bits/stdc++.h>
#define IN inline
#define eb emplace_back
#define fi first
#define se second
#define mp make_pair
using namespace std;

template <typename Tp>
IN void read(Tp &x) {
	x = 0; char ch = getchar(); int f = 0;
	for(; !isdigit(ch); f = (ch == '-' ? 1 : f), ch = getchar());
	for(; isdigit(ch); x = (x<<3)+(x<<1)+(ch^48), ch = getchar());
	if (f) x = ~x + 1;
}
int num[55];
IN void write(auto x) {
	if (!x) return putchar('0'), void();
	if (!x) putchar('-'), x = -x;
	while (x) num[++num[0]] = x % 10, x /= 10;
	while (num[0]) putchar(num[num[0]--] + '0');
}

typedef long long LL;
const int N = 250005;
const LL INF = 1e18;
int n, m, a[N], bz[N];
vector<pair<int, int>> E[N];
vector<int> G[N];

int sz[N], tp[N], dfc, son[N], dep[N], fa[N], dfn[N];
LL mn[N];
void dfs1(int x, int _fa) {
	sz[x] = 1;
	for(auto k : E[x]) {
		if (k.fi == _fa) continue;
		fa[k.fi] = x, mn[k.fi] = min(mn[x], (LL)k.se), dep[k.fi] = dep[x] + 1;
		dfs1(k.fi, x), sz[x] += sz[k.fi], son[x] = (sz[son[x]] < sz[k.fi] ? k.fi : son[x]);
	}
}
void dfs2(int x, int t) {
	tp[x] = t, dfn[x] = ++dfc;
	if (son[x]) dfs2(son[x], t);
	for(auto k : E[x]) {
		if (k.fi == fa[x] || k.fi == son[x]) continue;
		dfs2(k.fi, k.fi);
	}
}
IN int LCA(int x, int y) {
	while (tp[x] ^ tp[y]) {
		if (dep[tp[x]] < dep[tp[y]]) swap(x, y);
		x = fa[tp[x]];
	}
	return (dep[x] < dep[y] ? x : y);
}

int top, stk[N];
void build(int x) {
	if (!top) return stk[++top] = x, void();
	int z = LCA(stk[top], x);
	while (top && dfn[stk[top - 1]] >= dfn[z]) G[stk[top - 1]].eb(stk[top]), --top;
	if (stk[top] != z) G[z].eb(stk[top]), stk[top] = z;
	stk[++top] = x;
}

LL DP(int x) {
	LL s = 0;
	for(auto v : G[x]) s += DP(v);
	if (bz[x]) s = mn[x]; else s = min(s, mn[x]);
	return bz[x] = 0, G[x].clear(), s;
}

int main() {
	read(n);
	for(int i = 1, u, v, w; i < n; i++) read(u), read(v), read(w), E[u].eb(mp(v, w)), E[v].eb(mp(u, w));
	mn[1] = INF, dfs1(1, 0), dfs2(1, 1), read(m);
	for(int K; m; --m) {
		read(K);
		for(int i = 1; i <= K; i++) read(a[i]), bz[a[i]] = 1;
		sort(a + 1, a + K + 1, [](int x, int y){return dfn[x] < dfn[y];});
		build(1);
		for(int i = 1; i <= K; i++) build(a[i]);
		while (top) G[stk[top - 1]].eb(stk[top]), --top;
		write(DP(1)), puts("");
	}
}

[HEOI2014] 大工程

\(\text{Code}\)

#include <bits/stdc++.h>
#define IN inline
#define eb emplace_back
using namespace std;

template <typename Tp>
IN void read(Tp &x) {
	x = 0; char ch = getchar(); int f = 0;
	for(; !isdigit(ch); f = (ch == '-' ? 1 : f), ch = getchar());
	for(; isdigit(ch); x = (x<<3)+(x<<1)+(ch^48), ch = getchar());
	if (f) x = ~x + 1;
}

typedef long long LL;
const int N = 1e6 + 5;
int n, q;
vector<int> E[N], G[N];

int sz[N], tp[N], dfc, son[N], dep[N], fa[N], dfn[N];
void dfs1(int x, int _fa) {
	sz[x] = 1;
	for(auto v : E[x]) {
		if (v == _fa) continue;
		fa[v] = x, dep[v] = dep[x] + 1;
		dfs1(v, x), sz[x] += sz[v], son[x] = (sz[son[x]] < sz[v] ? v : son[x]);
	}
}
void dfs2(int x, int t) {
	tp[x] = t, dfn[x] = ++dfc;
	if (son[x]) dfs2(son[x], t);
	for(auto v : E[x]) {
		if (v == fa[x] || v == son[x]) continue;
		dfs2(v, v);
	}
}
IN int LCA(int x, int y) {
	while (tp[x] ^ tp[y]) {
		if (dep[tp[x]] < dep[tp[y]]) swap(x, y);
		x = fa[tp[x]];
	}
	return (dep[x] < dep[y] ? x : y);
}

int top, stk[N];
IN void insRT(int x) {
	if (!top) return stk[++top] = x, void();
	if (x == stk[top]) return;
	int z = LCA(x, stk[top]);
	while (top && dfn[stk[top - 1]] >= dfn[z]) G[stk[top - 1]].eb(stk[top]), --top;
	if (z != stk[top]) G[z].eb(stk[top]), stk[top] = z;
	stk[++top] = x;
}

int a[N], bz[N], K, siz[N], ans2, ans3, fmx[N], fmn[N];
LL ans1;
void dfs(int x) {
	siz[x] = bz[x], fmx[x] = 0, fmn[x] = N;
	int cmx = 0, cmn = N;
	for(auto v : G[x]) {
		int d = dep[v] - dep[x];
		dfs(v), ans1 += (LL)d * (K - siz[v]) * siz[v], siz[x] += siz[v];
		if (fmx[v] + d >= fmx[x]) cmx = fmx[x], fmx[x] = fmx[v] + d;
		else if (fmx[v] + d > cmx) cmx = fmx[v] + d;
		if (fmn[v] + d <= fmn[x]) cmn = fmn[x], fmn[x] = fmn[v] + d;
		else if (fmn[v] + d < cmn) cmn = fmn[v] + d;
	}
	if (bz[x] || cmx) ans2 = max(ans2, fmx[x] + cmx);
	if (bz[x]) ans3 = min(ans3, fmn[x]), fmn[x] = 0;
	else ans3 = min(ans3, fmn[x] + cmn);
	bz[x] = 0, G[x].clear();
}

int main() {
	read(n);
	for(int i = 1, u, v; i < n; i++) read(u), read(v), E[u].eb(v), E[v].eb(u);
	dfs1(1, 0), dfs2(1, 0), read(q);
	for(; q; --q) {
		read(K);
		for(int i = 1; i <= K; i++) read(a[i]), bz[a[i]] = 1;
		sort(a + 1, a + K + 1, [](int x, int y){return dfn[x] < dfn[y];});
		insRT(1);
		for(int i = 1; i <= K; i++) insRT(a[i]);
		while (top) G[stk[top - 1]].eb(stk[top]), --top;
		ans1 = ans2 = 0, ans3 = N, dfs(1), printf("%lld %d %d\n", ans1, ans3, ans2);
	}
}
posted @ 2023-02-03 11:26  leiyuanze  阅读(16)  评论(0编辑  收藏  举报