BB
众所周知,LCA有N种方法。一种种慢慢学。。。
方法
1. 倍增求法
2. 待续...
Problem List
//POJ 1986 lca模板
#include<bits/stdc++.h>
using namespace std;
const int maxn=4e4+5;
struct Edge{
int to;
int len;
};
vector<Edge> G[maxn];
int fa[maxn][21],dep[maxn],dist[maxn];
void dfs(int u)
{
for(int i=1;(1<<i)<=dep[u];i++) fa[u][i]=fa[fa[u][i-1]][i-1];//倍增DP
for(int i=0;i<G[u].size();i++)
{
Edge &e=G[u][i];
if(e.to==fa[u][0])continue;
dep[e.to]=dep[u]+1;
dist[e.to]=dist[u]+e.len;
fa[e.to][0]=u;
dfs(e.to);
}
}
int lca(int x,int y)
{
if(dep[x]>dep[y])swap(x,y);
int f=dep[y]-dep[x];
for(int i=0;(1<<i)<=f;i++)//二进制的思想,总能到达同dep
if((1<<i)&f)y=fa[y][i];
if(y==x)return x;
for(int i=20;i>=0;i--)//二进制思想,由大到小的减,总能到达1
if(fa[x][i]!=fa[y][i])
{
x=fa[x][i];
y=fa[y][i];
}
return fa[x][0];
}
int main()
{
int n,m;
scanf("%d%d",&n,&m);
int x,y,l;
char c;
for(int i=0;i<m;i++)
{
getchar();
scanf("%d %d %d %c",&x,&y,&l,&c);
G[x].push_back({y,l});
G[y].push_back({x,l});
}
dfs(1);
int k;
scanf("%d",&k);
while(k--)
{
scanf("%d%d",&x,&y);
printf("%d\n",dist[x]+dist[y]-2*dist[lca(x,y)]);
}
} 
京公网安备 11010502036488号