洛谷 P3806 【模板】点分治1
原题链接
点分治,能够处理一些树上路径问题
模板细节很多
#include<bits/stdc++.h> using namespace std; #define fr first #define se second #define et0 exit(0); #define rep(i, a, b) for(int i = (int)(a); i <= (int)(b); i ++) #define rrep(i, a, b) for(int i = (int)(a); i >= (int)(b); i --) #define IO ios::sync_with_stdio(false),cin.tie(0); typedef long long LL; typedef pair<int, int> PII; typedef pair<int, PII> PPI; typedef unsigned long long ULL; const int INF = 0X3f3f3f3f, N = 1e4 + 10, MOD = 1e9 + 7; const double eps = 1e-7, pi = acos(-1); int n, m; int idx, head[N]; int qus[N], res[N]; int root; int sz[N], mxs[N], mn; int vis[N], dis[N], frm[N], son[N], udx; struct NODE { int to, nxt, w; } eg[N << 1]; void add_edge(int u, int v, int w) { eg[idx].to = v; eg[idx].w = w; eg[idx].nxt = head[u]; head[u] = idx++; } void get_root(int u, int fa, int tot) { sz[u] = 1; mxs[u] = 0; for (int i = head[u]; ~i; i = eg[i].nxt) { int v = eg[i].to; if (vis[v] || v == fa) continue; get_root(v, u, tot); sz[u] += sz[v]; mxs[u] = max(mxs[u], sz[v]); } mxs[u] = max(mxs[u], tot - sz[u]); if (mxs[u] < mn) root = u, mn = mxs[u]; } void get_dis(int u, int fa, int dist, int from) { son[++udx] = u; dis[u] = dist; frm[u] = from; for (int i = head[u]; ~i; i = eg[i].nxt) { int v = eg[i].to; if (vis[v] || v == fa) continue; get_dis(v, u, dist + eg[i].w, from); } } bool cmp(int x, int y) { return dis[x] < dis[y]; } void calc(int u) { udx = 0; son[++udx] = u; frm[u] = u; dis[u] = 0; for (int i = head[u]; ~i; i = eg[i].nxt) { int v = eg[i].to; if (vis[v]) continue; get_dis(v, u, eg[i].w, v); } sort(son + 1, son + udx + 1, cmp); rep (i, 1, m) { if (res[i]) continue; int l = 1, r = udx; while (l < r) { int x = son[l], y = son[r], len = dis[x] + dis[y]; if (len < qus[i]) l++; else if (len > qus[i]) r--; else if (frm[x] == frm[y]) { if (frm[son[r - 1]] == frm[y]) r--; else l++; } else { res[i] = 1; break; } } } } void solve(int u) { vis[u] = 1; calc(u); for (int i = head[u]; ~i; i = eg[i].nxt) { int v = eg[i].to; if (vis[v]) continue; mn = INF; get_root(v, 0, sz[v]); solve(root); } } void work() { mn = INF; memset(head, -1, sizeof head); cin >> n >> m; rep (i, 2, n) { int u, v, w; cin >> u >> v >> w; add_edge(u, v, w), add_edge(v, u, w); } rep (i, 1, m) cin >> qus[i]; get_root(1, 0, n); solve(root); rep (i, 1, m) if (res[i]) { cout << "AYE" << endl; } else cout << "NAY" << endl; } signed main() { IO int test = 1; while (test--) { work(); } return 0; }
本文作者:xhy666
本文链接:https://www.cnblogs.com/xhy666/p/16821944.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具