BZOJ 3364: [Usaco2004 Feb]Distance Queries 距离咨询

来源:互联网 发布:网络媒介素养Ppt 编辑:程序博客网 时间:2024/05/22 06:32

LCA

每次询问两点的距离就是根到两点的距离和减去两倍的根到LCA的距离(ans=dis[x]+dis[y]-2*dis[LCA(x,y)])

#include<cstdio>#include<vector>#define RG register#define C (c=getchar())#define MAXN 100010#define maxlog 21using namespace std;  inline int read(){    static char c;int a=0;C;    while(c<'0'||c>'9')C;    while(c>='0'&&c<='9')a=a*10+c-'0',C;    return a;}  struct Edge{int to,v;};  int n,m,s;int t[maxlog],dep[MAXN],fa[MAXN][maxlog],dis[MAXN];vector<Edge>e[MAXN];  inline void add(int x,int y,int z){    e[x].push_back((Edge){y,z});    e[y].push_back((Edge){x,z});}  void dfs(int x){    for(int i=0;i<e[x].size();++i)    {        Edge &v=e[x][i];        if(v.to==fa[x][0]) continue;        dep[v.to]=dep[x]+1;        fa[v.to][0]=x;        dis[v.to]=v.v+dis[x];        dfs(v.to);    }}  inline void swap(int &a,int &b){int t=a;a=b;b=t;}  int LCA(int a,int b){    if(dep[a]>dep[b]) swap(a,b);    int i=19;    while(dep[a]<dep[b])    {        if(dep[b]-dep[a]>=t[i]) b=fa[b][i];        --i;    }    i=18;    if(a==b) return a;    while(fa[a][0]!=fa[b][0])    {        if(fa[a][i]!=fa[b][i]) a=fa[a][i],b=fa[b][i];        --i;    }    return fa[a][0];/*  for(int i=s;i>=0;--i)        if(dep[a]<dep[b]&&dep[a]<=dep[fa[b][i]])            b=fa[b][i];    for(int i=s;i>=0;--i)        if(fa[a][i]!=fa[b][i])            a=fa[a][i],b=fa[b][i];    if(a==b) return a;    else return fa[a][0];*/}  int main(){    n=read(),m=read();    RG int i,j;    for(i=1;i<=m;++i)    {        int x=read(),y=read(),z=read();        add(x,y,z);    }    fa[1][0]=0,dep[1]=0,dis[1]=0;    t[0]=1;    for(i=1;i<=19;++i)        t[i]=t[i-1]*2;    dfs(1);    for(j=1;j<=19;++j)        for(i=1;i<=n;++i)            fa[i][j]=fa[fa[i][j-1]][j-1];    int k=read();    while(k--)    {        int x=read(),y=read();        printf("%d\n",dis[x]+dis[y]-2*dis[LCA(x,y)]);    }    return 0;}


0 0