题解 P2726 【[SHOI2005]树的双中心】
1.[博客迁移20190713]题解 P4169 【[Violet]天使玩偶/SJY摆棋子】2.模拟题3.SP666 VOCV - Con-Junctions 题解4.Codeforces Round #900 (Div. 3)5.Codeforces Round 962 (Div. 3)6.题解 CF993E 【Nikita and Order Statistics】7.题解 P6891 【[JOISC2020]ビルの飾り付け 4】8.P2163 [SHOI2007] 园丁的烦恼9.[POI2011] LIZ-Lollipop10.Codeforces Round 973 (Div. 2)11.Codeforces Round 974 (Div. 3)12.NEERC2013题解13.CF1446C Xor Tree14.Codeforces Round 709 (Div. 1)15.Codeforces Round 975 (Div. 2)16.NEERC2014题解
17.题解 P2726 【[SHOI2005]树的双中心】
18.CF2019 F. Max Plus Min Plus Size19.Codeforces Round 757 (Div. 2)20.大工之星第一周题解首先,我们会有一个很简单的想法,枚举断边,产生两棵子树,然后在两棵树内分别求带权重心,计算贡献,这样的话复杂度是
那么我们要好好利用
考虑
所以
考虑
由于计算是动态的,我们考虑转移。
对于
如果
我们发现,只有两个候选项,重儿子和次重儿子。递归时顺带维护变化即可。
最坏情况可能会是一条到底的链,所以复杂度
code:
const int Maxn = 5e5 + 5, Maxm = 1e6 + 5;
int n, cnt = 0, w[Maxn], head[Maxn], ver[Maxm], nxt[Maxm];
inline void AddEdge(int u, int v) {
ver[++cnt] = v, nxt[cnt] = head[u], head[u] = cnt;
ver[++cnt] = u, nxt[cnt] = head[v], head[v] = cnt;
}
int dep[Maxn], fat[Maxn], son[Maxn], son2[Maxn];
int sze[Maxn], g[Maxn], cut, ans = INT_MAX;
inline void DfsFir(int u) {
sze[u] = w[u];
for (int i = head[u]; i; i = nxt[i]) {
if (ver[i] == fat[u]) continue;
dep[ver[i]] = dep[u] + 1; fat[ver[i]] = u;
DfsFir(ver[i]); sze[u] += sze[ver[i]];
g[u] += g[ver[i]] + sze[ver[i]];
if (sze[ver[i]] > sze[son[u]]) son2[u] = son[u], son[u] = ver[i];
else if (sze[ver[i]] > sze[son2[u]]) son2[u] = ver[i];
}
}
inline void getans(int u, int val, int all, int &ret) {
chkmin(ret, val); int v = son[u];
if (v == cut || sze[son[u]] < sze[son2[u]]) v = son2[u];
if (!v) return;
if (2 * sze[v] > all) getans(v, val + all - 2 * sze[v], all, ret);
}
inline void DfsSec(int u) {
for (int i = head[u]; i; i = nxt[i]) {
if (ver[i] == fat[u]) continue;
cut = ver[i]; int x = INT_MAX, y = INT_MAX;
for (int pos = u; pos; pos = fat[pos]) sze[pos] -= sze[ver[i]];
getans(1, g[1] - g[ver[i]] - dep[ver[i]] * sze[ver[i]], sze[1], x);
getans(ver[i], g[ver[i]], sze[ver[i]], y); chkmin(ans, x + y);
for (int pos = u; pos; pos = fat[pos]) sze[pos] += sze[ver[i]];
DfsSec(ver[i]);
}
}
signed main(void) {
// file("");
read(n);
for (int i = 1, u, v; i < n; i++)
read(u), read(v), AddEdge(u, v);
for (int i = 1; i <= n; i++) read(w[i]);
DfsFir(1); DfsSec(1); writeln(ans);
// fwrite(pf, 1, o1 - pf, stdout);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现