Codevs 2370 小机房的树

来源:互联网 发布:流星网络电视安卓版vt 编辑:程序博客网 时间:2024/05/19 02:04

传送
LCA的应用。
用Tarjan的方法来找最近公共祖先,dfs过程中求出当前节点到根节点的距离。
那么ans=dep[u]-dep[lca]+dep[v]-dep[lca];

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#define LL long long #define M 750009 using namespace std;int head[M],to[2*M],nxt[2*M],tt,cost[2*M];int qhead[M],qto[2*M],qnxt[2*M],qtt,lca[2*M],dep[2*M];int f[M];int n,m,root;bool vis[M];void add(int x,int y,int z){    to[++tt]=y;    nxt[tt]=head[x];    head[x]=tt;    cost[tt]=z;}void qadd(int x,int y){    qto[++qtt]=y;    qnxt[qtt]=qhead[x];    qhead[x]=qtt;}int find(int x){    return f[x]==x?x:f[x]=find(f[x]); }void dfs(int x){    f[x]=x;    vis[x]=1;    for(int i=head[x];i;i=nxt[i])    if(!vis[to[i]])    {        dep[to[i]]=dep[x]+cost[i];        dfs(to[i]);        f[to[i]]=x;    }    for(int i=qhead[x];i;i=qnxt[i])    if(vis[qto[i]])    {        lca[i]=find(qto[i]);        if(i%2) lca[i+1]=lca[i];        else lca[i-1]=lca[i];    }}int main(){    scanf("%d",&n);    for(int i=1;i<n;i++)    {        int x,y,z;        scanf("%d%d%d",&x,&y,&z);        add(x,y,z);add(y,x,z);    }    scanf("%d",&m);    for(int i=1;i<=m;i++)    {        int x,y;        scanf("%d%d",&x,&y);        qadd(x,y);qadd(y,x);    }    root=0;    dfs(root);    for(int i=1;i<=m;i++)    {        int ans=dep[qto[2*i]]-dep[lca[2*i]]+dep[qto[2*i-1]]-dep[lca[2*i]];        printf("%d\n",ans);    }    return 0;}
原创粉丝点击