标签:dfs tmp 处理 struct 节点 type cstring using 影响
我们先考虑根的情况, 看是否能够最后停在根节点上
我们设两棵子树 \(u\) , \(v\) , 那么 \(u\) 长出一个点, \(v\) 再长出一个点, 这两个点的影响就抵消了对吧
那么我们就是看是否能子树内互相抵消最后使榕树之心停在根节点上
最大的一棵子树肯定是最难消的, 我们考虑用其他的子树去消它, 然后其他的子树内部再消
我们设这棵树以 \(u\) 为根, 最大的一棵子树以 \(v\) 为根, 那么可以分为这么几种情况讨论
那么 \(f[v]\) 怎么推呢
根据以上过程我们可以发现, 字母定义如上
\[
\displaystyle f[u] = \begin{cases}\lfloor \frac{sz[u] - 1}{2}\rfloor , sz[v] \leq sz[u] - 1 - sz[v]\\\lfloor \frac{sz[u] - 1}{2}\rfloor , sz[v] - 2 * f[v] \leq sz[u]- 1 - sz[v]\\f[v] + sz[u] - sz[v] - 1, sz[v] - 2 * f[v] > sz[u]-1-sz[v]\end{cases}
\]
这样我们就处理出了根节点的情况
那么对于任意一个点怎么做呢?
我们可以看做先伸出了 \(1 \to x\) 这一条链, 此时榕树之心在 \(x\)
然后再看这条链上的其他子树互相消看是否能够消光就行了
但 \(x\) 有可能在 \(1\) 的最大的子树里面, 所以我们要记一下次大子树
#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
const int N = 100005;
using namespace std;
int W, n, T, head[N], cnt, dep[N], sz[N], mson[N], sson[N], f[N], ans[N];
struct edge { int to, nxt; } e[N << 1];
template < typename T >
inline T read()
{
T x = 0, w = 1; char c = getchar();
while(c < '0' || c > '9') { if(c == '-') w = -1; c = getchar(); }
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * w;
}
inline void adde(int u, int v) { e[++cnt] = (edge) { v, head[u] }, head[u] = cnt; }
void dfs(int u, int fa)
{
dep[u] = dep[fa] + 1, sz[u] = 1;
for(int v, i = head[u]; i; i = e[i].nxt)
{
v = e[i].to; if(v == fa) continue;
dfs(v, u), sz[u] += sz[v];
if(sz[v] > sz[mson[u]])
sson[u] = mson[u], mson[u] = v;
else if(sz[v] > sz[sson[u]])
sson[u] = v;
}
if(2 * sz[mson[u]] <= sz[u] - 1 || 2 * (sz[mson[u]] - f[mson[u]]) <= sz[u] - 1)
f[u] = (sz[u] - 1) / 2;
else
f[u] = f[mson[u]] + sz[u] - sz[mson[u]] - 1;
}
void dfs2(int u, int fa, int id)
{
int tmp = sz[id] > sz[mson[u]] ? id : mson[u];
if(2 * sz[tmp] <= n - dep[u] || 2 * (sz[tmp] - f[tmp]) <= n - dep[u])
ans[u] = (n - dep[u]) & 1 ? 0 : 1;
for(int v, i = head[u]; i; i = e[i].nxt)
{
v = e[i].to; if(v == fa) continue;
dfs2(v, u, (v == mson[u] ? (sz[id] > sz[sson[u]] ? id : sson[u]) : tmp));
}
}
int main()
{
W = read <int> (), T = read <int> ();
while(T--)
{
n = read <int> (), cnt = 0;
for(int i = 1; i <= n; i++)
head[i] = mson[i] = sson[i] = ans[i] = 0;
for(int u, v, i = 1; i < n; i++)
{
u = read <int> (), v = read <int> ();
adde(u, v), adde(v, u);
}
dfs(1, 0), dfs2(1, 0, 0);
if(W == 3) printf("%d\n", ans[1]);
else
{
for(int i = 1; i <= n; i++)
printf("%d", ans[i]);
puts("");
}
}
return 0;
}
标签:dfs tmp 处理 struct 节点 type cstring using 影响
原文地址:https://www.cnblogs.com/ztlztl/p/12203583.html