虚树模板

[SDOI2011] 消耗战

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] 大工程

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 @   leiyuanze  阅读(19)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示