AT_agc034_e [AGC034E] Complete Compress 题解
可以发现若最终所有棋子移动到
于是只需求出哪些
设
考虑
于是此时的最优策略为其他所有子树的棋子均选择
这样其他所有子树的棋子均被移到
也就是
如果
以
发现需要以每个点为根的 DP 值,换根 DP 即可。
#include <cstdio>
#include <algorithm>
#define int long long
using namespace std;
inline int R()
{
int q = 0;
char c = getchar();
while (c < '0' || c > '9')
c = getchar();
while (c >= '0' && c <= '9')
q = q * 10 + c - '0', c = getchar();
return q;
}
inline int I()
{
char c = getchar();
while (c < '0' || c > '9')
c = getchar();
return c - '0';
}
struct E
{
int v, t;
} e[2000050];
int n, c, q = 1e18, a[1000050], s[1000050], f[1000050], g[1000050], p[1000050], z[1000050][2], o[1000050][2], h[1000050];
void A(int u, int v)
{
e[++c] = {v, h[u]};
h[u] = c;
}
void D1(int u, int k)
{
s[u] = a[u];
for (int i = h[u], v; i; i = e[i].t)
if ((v = e[i].v) != k)
D1(v, u), p[u] += f[v] + s[v], g[u] += g[v] + s[v], s[u] += s[v];
for (int i = h[u], v; i; i = e[i].t)
if ((v = e[i].v) != k)
{
if (f[v] + s[v] + g[v] + s[v] > o[u][0])
z[u][1] = z[u][0], z[u][0] = v, o[u][1] = o[u][0], o[u][0] = f[v] + s[v] + g[v] + s[v];
else if (f[v] + s[v] + g[v] + s[v] > o[u][1])
z[u][1] = v, o[u][1] = f[v] + s[v] + g[v] + s[v];
}
if (o[u][0] > g[u])
f[u] = o[u][0] - g[u];
else
f[u] = p[u] & 1;
}
void D2(int u, int k)
{
int S = s[u], F = f[u], P = p[u], G = g[u], Z0 = z[u][0], Z1 = z[u][1], O0 = o[u][0], O1 = o[u][1];
for (int i = h[u], v; i; i = e[i].t)
if ((v = e[i].v) != k)
{
s[u] -= s[v];
g[u] -= g[v] + s[v];
p[u] -= f[v] + s[v];
if (z[u][0] == v)
z[u][0] = z[u][1], o[u][0] = o[u][1];
if (o[u][0] > g[u])
f[u] = o[u][0] - g[u];
else
f[u] = p[u] & 1;
s[v] += s[u];
g[v] += g[u] + s[u];
p[v] += f[u] + s[u];
if (f[u] + s[u] + g[u] + s[u] > o[v][0])
z[v][1] = z[v][0], z[v][0] = u, o[v][1] = o[v][0], o[v][0] = f[u] + s[u] + g[u] + s[u];
else if (f[u] + s[u] + g[u] + s[u] > o[v][1])
z[v][1] = u, o[v][1] = f[u] + s[u] + g[u] + s[u];
if (o[v][0] > g[v])
f[v] = o[v][0] - g[v];
else
f[v] = p[v] & 1;
D2(v, u);
s[u] = S, f[u] = F, p[u] = P, g[u] = G, z[u][0] = Z0, z[u][1] = Z1, o[u][0] = O0, o[u][1] = O1;
}
}
signed main()
{
// freopen("charlotte.in", "r", stdin);
// freopen("charlotte.out", "w", stdout);
while (~scanf("%d", &n))
{
for (int i = 1; i <= n; ++i)
a[i] = I();
for (int i = 1, u, v; i < n; ++i)
u = R(), v = R(), A(u, v), A(v, u);
D1(1, 0);
D2(1, 0);
for (int u = 1; u <= n; ++u)
if (!f[u])
q = min(q, g[u] >> 1);
printf("%lld\n", q == 1e18 ? -1 : q);
c = 0;
q = 1e18;
for (int i = 1; i <= n; ++i)
a[i] = s[i] = f[i] = g[i] = p[i] = z[i][0] = z[i][1] = o[i][0] = o[i][1] = h[i] = 0;
}
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具