Ural 1471 Tree

来源:互联网 发布:淘宝店铺怎么打广告 编辑:程序博客网 时间:2024/06/06 04:10

询问一棵树的任意两个节点的最短距离。

裸的lca。

#include<iostream>#include<cstdio>#include<algorithm>#include<queue>#include<map>#include<vector>#include<stack>#include<cstring>using namespace std;const int maxn=500001;struct Node{int val,to,next;}node[2*maxn];int head[maxn],tot;int fa[maxn];int ancestor[maxn];int vis[maxn];int ans[maxn];int dis[maxn];vector<pair<int,int> > que[maxn];void addedge(int u,int v,int w){    node[tot].val=w,node[tot].to=v,node[tot].next=head[u],head[u]=tot++;    node[tot].val=w,node[tot].to=u,node[tot].next=head[v],head[v]=tot++;}int find(int x){    return x==fa[x]?fa[x]:fa[x]=find(fa[x]);}int merge(int a,int b){    int pa=find(a);    int fb=find(b);    if(pa!=fb)    {        fa[fb]=pa;        return 1;    }    return 0;}void dfs(int u,int f)// distance{    int v;    for(int i=head[u];i!=-1;i=node[i].next)    {        v=node[i].to;        if(v!=f)        {            dis[v]=dis[u]+node[i].val;            dfs(v,u);        }    }}void tarjan(int u,int f){    int v,w;    ancestor[find(u)]=u;    for(int i=head[u];i!=-1;i=node[i].next)    {        v=node[i].to;        if(v!=f)        {            tarjan(v,u);            merge(u,v);            ancestor[find(u)]=u;        }    }    vis[u]=1;    for(unsigned int i=0;i<que[u].size();i++)    {        v=que[u][i].first;        w=que[u][i].second;        if(vis[v])        {            int tmp=ancestor[find(v)];            ans[w]=dis[u]+dis[v]-2*dis[tmp];        }    }}int main(){    //freopen("in","r",stdin);    int n,u,v,w;    tot=0;    memset(head,-1,sizeof(head));    scanf("%d",&n);    for(int i=0;i<=n;i++)    fa[i]=i;    for(int i=0;i<n-1;i++)    {        scanf("%d%d%d",&u,&v,&w);        addedge(u,v,w);    }    int q;    scanf("%d",&q);    for(int i=1;i<=q;i++)    {        scanf("%d%d",&u,&v);        que[u].push_back(make_pair(v,i));        que[v].push_back(make_pair(u,i));    }    dfs(0,-1);    memset(vis,0,sizeof(vis));    tarjan(0,-1);    for(int i=1;i<=q;i++)    printf("%d\n",ans[i]);    return 0;}