标准求法

//O(nlogn)-O(logn)
#include<cstdio>
#include<algorithm> 
using namespace std;
const int maxn=100010;
int first[maxn],next[maxn*2],to[maxn*2],dis[maxn*2];
int n,m;
void AddEdge(int a,int b,int c)
{
     to[++m]=b;
     dis[m]=c;
     next[m]=first[a];
     first[a]=m;
}
int dep[maxn],fa[maxn],cost[maxn],anc[20][maxn];
void dfs(int x)
{
    dep[x]=dep[fa[x]]+1;
    for(int i=first[x];i;i=next[i])
    {
       if(to[i]!=fa[x])
       {
           fa[to[i]]=x;
           cost[to[i]]=cost[x]+dis[i];
           dfs(to[i]);
       }
    }
}
void preprocess()
{
    for(int i=1;i<=n;i++) anc[0][i]=fa[i];
    for(int j=1;(1<<j)<=n;j++)
       for(int i=1;i<=n;i++)
          if(anc[j-1][i])
          {
              int a=anc[j-1][i];
              anc[j][i]=anc[j-1][a];
          }
}
int LCA(int p,int q)
{
    if(dep[p]<dep[q]) swap(p,q);
    int log=1;
    for(;(1<<log)<=dep[p];log++); log--;
    for(int i=log;i>=0;i--) if(dep[p]-dep[q]>=(1<<i)) p=anc[i][p];
    if(p==q) return p;
    for(int i=log;i>=0;i--)
       if(anc[i][p]!=anc[i][q])
       {
           p=anc[i][p];
           q=anc[i][q];
       }
    return fa[p];
}
int main()
{
    int a,b,c,Q;
    scanf("%d",&n);
    for(int i=1;i<n;i++)
    {
        scanf("%d%d%d",&a,&b,&c);
        AddEdge(a,b,c);
        AddEdge(b,a,c);
    }
    scanf("%d",&Q);
    dfs(1);
    preprocess();
    while(Q--)
    {
        scanf("%d%d",&a,&b);
        c=LCA(a,b);
        printf("%d %d\n",dep[a]+dep[b]-dep[c]*2+1,cost[a]+cost[b]-cost[c]*2);
    }
    return 0;
}
View Code

相关文章: