终于又打开了一个天坑。。。。点分治真的是好东西呢(QwQ)
点分治的核心思想在于把问题划分为每一个点可以统计的形式,然后对树上的点进行分治。为了保证复杂度为(log),需要每次都找询问子树的重心。
可以很好的解决关于所有链信息的询问。通常离线。
#include <bits/stdc++.h>
using namespace std;
const int M = 110;
const int N = 10010;
const int INF = 10000010;
int n, m, cnt, head[N];
struct edge {
int nxt, to, w;
edge (int _nxt = 0, int _to = 0, int _w = 0) {
nxt = _nxt, to = _to, w = _w;
}
}e[N << 1];
void add_len (int u, int v, int w) {
e[++cnt] = edge (head[u], v, w); head[u] = cnt;
e[++cnt] = edge (head[v], u, w); head[v] = cnt;
}
int rt, sum, sz[N], qry[M], rem[N], res[M], dis[N], maxp[N];
bool vis[N], have[INF];
void get_root (int u, int fa) {
sz[u] = 1, maxp[u] = 0;
for (int i = head[u]; i; i = e[i].nxt) {
int v = e[i].to;
if (v != fa && !vis[v]) { //vis 限制只访问这棵子树的信息。
get_root (v, u);
sz[u] += sz[v];
maxp[u] = max (maxp[u], sz[v]);
}
}
maxp[u] = max (maxp[u], sum - sz[u]); //sum 是当前子树大小
if (maxp[u] < maxp[rt]) rt = u;
}
void get_dis (int u, int fa) {
rem[++rem[0]] = dis[u];
for (int i = head[u]; i; i = e[i].nxt) {
int v = e[i].to;
if (!vis[v] && v != fa) {
dis[v] = dis[u] + e[i].w;
get_dis (v, u);
}
}
}
queue <int> q;
void calc (int u) {
for (int i = head[u]; i; i = e[i].nxt) {
int v = e[i].to;
if (!vis[v]) {
rem[0] = 0, dis[v] = e[i].w;
get_dis (v, u);
for (int j = 1; j <= rem[0]; ++j) {
for (int k = 1; k <= m; ++k) {
if (qry[k] >= rem[j]) {
res[k] |= have[qry[k] - rem[j]];
}
}
}
for (int j = 1; j <= rem[0]; ++j) {
q.push (rem[j]); have[rem[j]] = true;
}
}
}
while (!q.empty ()) have[q.front ()] = false, q.pop ();
}
void solve (int u) {
//have[i] -> 是否存在 dis = i 的路径
vis[u] = have[0] = true; calc (u);
//只能访问 u 的子树, 计算 u 子树的状态
for (int i = head[u]; i; i = e[i].nxt) {
int v = e[i].to;
if (!vis[v]) {
sum = sz[v];
maxp[rt = 0] = INF;
get_root (v, 0);
solve (rt);
}
}
}
int main () {
cin >> n >> m;
for (int i = 1; i <= n - 1; ++i) {
static int u, v, w;
cin >> u >> v >> w;
add_len (u, v, w);
}
for (int i = 1; i <= m; ++i) cin >> qry[i];
maxp[rt] = sum = n;
get_root (1, 0);
solve (rt);
for (int i = 1; i <= m; ++i) {
puts (res[i] ? "AYE" : "NAY");
}
}