[复习]LCA Tree

来源:互联网 发布:数据库中存储的是 编辑:程序博客网 时间:2024/06/14 01:51

题目背景
SOURCE:NOIP2015-SHY

题目描述
给出一棵带有边权的树,问两点之间的距离。

输入格式
第一行两个整数 n 和 m ,分别表示点数和询问数。
接下来 n-1 行,每行三个整数 x,y,z,表示 x 与 y 通过一条权为 z 的边连接。
接下来 m 行,每行两个整数 x,y,代表一组询问。

输出格式
输出 m 行,每行一个整数,对应一组询问的答案。

样例数据
输入

3 3
1 2 1
1 3 2
1 2
1 3
2 3

输出

1
2
3

备注
【数据范围】
对 30% 的输入数据 :
1≤n,m≤1000
对 100% 的输入数据 :
1≤n,m≤100000;1≤z≤10000

分析: LCA模板

代码:

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<string>#include<ctime>#include<cmath>#include<algorithm>#include<cctype>#include<iomanip>#include<queue>#include<set>using namespace std;int getint(){    int sum=0,f=1;    char ch;    for(ch=getchar();!isdigit(ch)&&ch!='-';ch=getchar());    if(ch=='-')    {        f=-1;        ch=getchar();    }    for(;isdigit(ch);ch=getchar())        sum=(sum<<3)+(sum<<1)+ch-48;    return sum*f;}const int N=100010;int n,m,tot;int first[N],nxt[N*2],to[N*2],w[N*2];int fa[N][25],dep[N],dis[N];bool visit[N];void addedge(int x,int y,int z){    tot++;    nxt[tot]=first[x];    first[x]=tot;    to[tot]=y;    w[tot]=z;    tot++;    nxt[tot]=first[y];    first[y]=tot;    to[tot]=x;    w[tot]=z;}void dfs(int u){    for(int p=first[u];p;p=nxt[p])    {        int v=to[p];        if(!visit[v])        {            visit[v]=true;            dep[v]=dep[u]+1;            dis[v]=dis[u]+w[p];            fa[v][0]=u;            for(int i=1;i<=20;++i)                fa[v][i]=fa[fa[v][i-1]][i-1];            dfs(v);        }    }}int lca(int x,int y){    if(dep[x]<dep[y])        swap(x,y);    int len=dep[x]-dep[y];    for(int i=20;i>=0;i--)        if(len&(1<<i))            x=fa[x][i];    if(x==y)        return x;    for(int i=20;i>=0;i--)        if(fa[x][i]!=fa[y][i])        {            x=fa[x][i];            y=fa[y][i];        }    return fa[x][0];}int main(){    //freopen("LCA.in","r",stdin);    //freopen("LCA.out","w",stdout);    int x,y,z;    n=getint(),m=getint();    for(int i=1;i<n;++i)    {        x=getint(),y=getint(),z=getint();        addedge(x,y,z);    }    dep[1]=0,dis[1]=0;    visit[1]=true;    dfs(1);    while(m--)    {        x=getint(),y=getint();        z=lca(x,y);        cout<<dis[x]+dis[y]-2*dis[z]<<'\n';    }    return 0;}

本题结。