POJ 1330 Nearest Common Ancestors 最近公共祖先
LCA模板题,用倍增法去写
首先把每一个节点的向上个祖先给枚举出来
再把要求公共祖先的两个节点拉到同一深度
向上不断利用倍增一起跳跃同样层数到他们各自的非公共祖先的祖先节点
最后他们一起到达共同祖先节点的子节点,再同时向上走一位即可
在这个过程中,同时维护cost
即可
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
const int N = 40001;
int p[N][31], cost[N][31], lv[N];
vector<pii> G[N];
int dfs(int x,int fx) {
p[x][0]=fx;
lv[x]=lv[fx]+1;
for(int i=1;i<31;i++) {
p[x][i]=p[p[x][i-1]][i-1];
cost[x][i]=cost[p[x][i-1]][i-1]+cost[x][i-1];
}
for(auto u:G[x]){
if(u.first==fx) continue;
cost[u.first][0]=u.second;
dfs(u.first,x);
}
}
int lca(int x,int y) {
if(lv[x]>lv[y]) swap(x,y);
int tmp = lv[y]-lv[x], ans = 0;
for(int i=0;tmp;i++,tmp>>=1)
if(tmp&1) ans += cost[y][i],y=p[y][i];
if(y==x) return ans;
for(int i=30;i>=0&&y!=x;i--) {
if(p[x][i]==p[y][i]) continue;
ans+=cost[x][i]+cost[y][i];
x=p[x][i];
y=p[y][i];
}
ans+=cost[x][0]+cost[y][0];
return ans;
}
int n,m,a,b,c;
int solve(){
for(int i=0;i<N;i++) G[i].clear();
cin>>n>>m;
for(int i=1;i<n;i++) {
cin>>a>>b>>c;
G[a].push_back(make_pair(b,c));
G[b].push_back(make_pair(a,c));
}
dfs(1,0);
while(m--){
cin>>a>>b;
cout<<lca(a,b)<<endl;
}
}
int main(){
int t;
cin>>t;
while(t--) solve();
}
标签:
ACM
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· 展开说说关于C#中ORM框架的用法!
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?