P4281 [AHOI2008]紧急集合 聚会 题解
就是求三个点到同一个点的最短路径。
Solution
我们知道在一颗树上,三个点的 只有两个点。
那最后肯定是移动到其中一个点上。
那移动到哪个点上更优呢。
我们都求出来然后取个 不就行了嘛 /qd
于是这个蓝题就变成了 板子。
/* Work by: TLE_Automation */ #include<cmath> #include<queue> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define LL long long //#define int long long using namespace std; const int N = 1e6 + 10; const int MAXN = 2e5 + 10; inline char readchar() { static char buf[100000], *p1 = buf, *p2 = buf; return p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 100000, stdin), p1 == p2) ? EOF : *p1++; } inline int read() { #define readchar getchar int res = 0, f = 0;char ch = readchar(); for(; !isdigit(ch); ch = readchar()) if(ch == '-') f = 1; for(; isdigit(ch); ch = readchar()) res = (res << 1) + (res << 3) + (ch ^ '0'); return f ? -res : res; } inline void print(int x) { if (x < 0 ) putchar('-'), x = -x; if (x > 9 ) print(x / 10); putchar(x % 10 + '0'); } int n, Q, head[N], dep[N], f[N][30], num_adge = 0; struct Node {int u, v, nxt;} e[N]; void add(int u, int v) {e[++num_adge] = (Node) {u, v, head[u]}, head[u] = num_adge;} void dfs(int u, int fa) { dep[u] = dep[fa] + 1, f[u][0] = fa; for(int i = 1; i <= 20; i++) f[u][i] = f[f[u][i - 1]][i - 1]; for(int i = head[u]; i; i = e[i].nxt) { int v = e[i].v; if(v ^ fa) dfs(v, u); } } int LCA(int x, int y) { if(dep[x] < dep[y]) swap(x, y); for(int i = 20; i >= 0; i--) { if(dep[f[x][i]] >= dep[y]) x = f[x][i]; if(x == y) return x; } for(int i = 20; i >= 0; i--) { if(f[x][i] != f[y][i]) x = f[x][i], y = f[y][i]; } return f[x][0]; } int ans1 = 0, ans2 = 0; int lca1, lca2; int Ans; signed main() { n = read(), Q = read(); for(int i = 1, u, v; i <= n - 1; i++) u = read(), v = read(), add(u, v), add(v, u); dfs(1, 0); for(int i = 1; i <= Q; i++) { int a = read(), b = read(), c = read(); int t1 = LCA(a, b), t2 = LCA(b, c), t3 = LCA(a, c); // printf("\n%d %d %d\n\n", t1, t2, t3); if(t1 == t2) { lca1 = t1, lca2 = t3; ans1 = dep[a] + dep[lca1] - 2 * dep[LCA(lca1, a)] + dep[b] + dep[lca1] - 2 * dep[LCA(lca1, b)] + dep[c] + dep[lca1] - 2 * dep[LCA(lca1, c)]; ans2 = dep[a] + dep[lca2] - 2 * dep[LCA(lca2, a)] + dep[b] + dep[lca2] - 2 * dep[LCA(lca2, b)] + dep[c] + dep[lca2] - 2 * dep[LCA(lca2, c)]; } else if(t1 == t3) { lca1 = t1, lca2 = t2; ans1 = dep[a] + dep[lca1] - 2 * dep[LCA(lca1, a)] + dep[b] + dep[lca1] - 2 * dep[LCA(lca1, b)] + dep[c] + dep[lca1] - 2 * dep[LCA(lca1, c)]; ans2 = dep[a] + dep[lca2] - 2 * dep[LCA(lca2, a)] + dep[b] + dep[lca2] - 2 * dep[LCA(lca2, b)] + dep[c] + dep[lca2] - 2 * dep[LCA(lca2, c)]; } else if(t2 == t3) { lca1 = t2, lca2 = t1; ans1 = dep[a] + dep[lca1] - 2 * dep[LCA(lca1, a)] + dep[b] + dep[lca1] - 2 * dep[LCA(lca1, b)] + dep[c] + dep[lca1] - 2 * dep[LCA(lca1, c)]; ans2 = dep[a] + dep[lca2] - 2 * dep[LCA(lca2, a)] + dep[b] + dep[lca2] - 2 * dep[LCA(lca2, b)] + dep[c] + dep[lca2] - 2 * dep[LCA(lca2, c)]; } if(ans1 < ans2) Ans = lca1; else Ans = lca2; printf("%d %d\n", Ans, min(ans1, ans2)); } }
本文作者:TLE_Automation
本文链接:https://www.cnblogs.com/tttttttle/p/16323153.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现