AHOI2008 聚会
生活随笔
收集整理的這篇文章主要介紹了
AHOI2008 聚会
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
洛谷
BZOJ
分析
任意兩個(gè)點(diǎn)的最短距離一定經(jīng)過(guò)它們的 \(LCA\) ,推廣到三個(gè)點(diǎn)的情況,設(shè)這三個(gè)點(diǎn)分別是 \(x,y,z\) ,先求出 \(x, y\) 的 \(LCA\) 為 \(w\) ,最后的 \(pos\) 可能是在 \(w\) 和 \(z\) 的 \(LCA\) 處,但不難發(fā)現(xiàn), \(w\) 是兩個(gè)人在走,而 \(z\) 只有一個(gè)人,所以將 \(pos\) 放在 \(w\) 處顯然會(huì)更合適。最后,手推樣例發(fā)現(xiàn)三個(gè) \(LCA\) 中取深度最大的 \(LCA\) 最合適。
代碼
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define il inline
#define re register
#define maxn 500003
#define tie0 cin.tie(0),cout.tie(0)
#define fastio ios::sync_with_stdio(false)
#define File(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout)
using namespace std;
typedef long long ll;template <typename T> inline void read(T &x) {T f = 1; x = 0; char c;for (c = getchar(); !isdigit(c); c = getchar()) if (c == '-') f = -1;for ( ; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);x *= f;
}struct edge {int to, nxt;
} e[maxn<<1];int n, m, pos, cost;
int head[maxn], cnt;
int fa[maxn][25], dep[maxn], lg[maxn];void addedge(int u, int v) {e[++cnt].to = v, e[cnt].nxt = head[u], head[u] = cnt;e[++cnt].to = u, e[cnt].nxt = head[v], head[v] = cnt;
}void dfs(int u, int _fa) {fa[u][0] = _fa, dep[u] = dep[_fa] + 1;for (int i = 1; (1 << i) <= dep[u]; ++i) fa[u][i] = fa[fa[u][i-1]][i-1];for (int i = head[u]; i; i = e[i].nxt) {int v = e[i].to;if (v == _fa) continue;dfs(v, u);}
}int LCA(int u, int v) {if (dep[u] < dep[v]) swap(u, v);while (dep[u] > dep[v]) u = fa[u][lg[dep[u]-dep[v]]-1];if (u == v) return u;for (int i = lg[dep[u]]; i >= 0; --i)if (fa[u][i] != fa[v][i])u = fa[u][i], v = fa[v][i];return fa[u][0];
}void solve(int x, int y, int z) {int f1, f2, f3;f1 = LCA(x, y), f2 = LCA(y, z), f3 = LCA(x, z);pos = dep[f1] > dep[f2] ? f1 : f2;pos = dep[pos] > dep[f3] ? pos : f3;cost = dep[x] + dep[y] + dep[z] - dep[f1] - dep[f2] - dep[f3];
}int main() {int u, v, w;read(n), read(m);for (int i = 1; i <= n; ++i) lg[i] = lg[i-1] + (1 << lg[i-1] == i);for (int i = 1; i < n; ++i) {read(u), read(v);addedge(u, v);}dfs(1, 0);for (int i = 1; i <= m; ++i) {cost = 0;read(u), read(v), read(w);solve(u, v, w);printf("%d %d\n", pos, cost);}return 0;
}
轉(zhuǎn)載于:https://www.cnblogs.com/hlw1/p/11437298.html
總結(jié)
以上是生活随笔為你收集整理的AHOI2008 聚会的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: SCOI2009 最长距离
- 下一篇: NOIP2013 货车运输