HDU 2586 How far away? LCA模板

来源:互联网 发布:nginx php exec 权限 编辑:程序博客网 时间:2024/05/22 04:25

    给一棵树,若干个查询,每次查询树上两点的距离。第一道LCA的题..完全是裸的,把查询存起来,直接tarjan就可以。res[i][0],res[i][1],res[i][2]分别表示第i个查询的起点,终点和起点终点的最近公共祖先,记dis[x]为x到根节点的距离,那么dis(0,1)就是dis[0]+dis[1]-2*dis[2].

#include <iostream>#include <cstdio>#include <algorithm>#include <memory.h>#include <cmath>using namespace std;typedef long long ll;const int maxn=40000+40;struct node{    int w,v;    int next;}edge[maxn<<1],query[500];bool vis[maxn];int g[maxn],gg[maxn];int res[maxn][3];int m,n,k,p,q;int en,eq;int test;int fa[maxn];int dis[maxn];int find(int x){    if (x!=fa[x]) return fa[x]=find(fa[x]);    return x;}void tarjan(int u){    vis[u]=true;    fa[u]=u;    for (int j=gg[u]; j!=-1; j=query[j].next)    {        if (vis[query[j].v])        {            res[query[j].w][2]=find(query[j].v);        }    }    for (int j=g[u]; j!=-1; j=edge[j].next)    {        if (!vis[edge[j].v])        {            dis[edge[j].v]=dis[u]+edge[j].w;            tarjan(edge[j].v);            fa[edge[j].v]=u;        }    }}int main(){//    freopen("in.txt","r",stdin);    scanf("%d",&test);    while (test--)    {        memset(vis,false,sizeof vis);        memset(dis,0,sizeof dis);        scanf("%d",&n);        scanf("%d",&m);        memset(g,-1,sizeof g);        memset(gg,-1,sizeof gg);        en=eq=0;        int x,y,z;        for (int i=1; i<n; i++)        {            scanf("%d%d%d",&x,&y,&z);            edge[en].w=z;            edge[en].v=y;            edge[en].next=g[x];            g[x]=en;            en++;            edge[en].w=z;            edge[en].v=x;            edge[en].next=g[y];            g[y]=en;            en++;        }        for (int i=1; i<=m; i++)        {            scanf("%d%d",&x,&y);            query[eq].v=y;            query[eq].w=i;            query[eq].next=gg[x];            gg[x]=eq;            eq++;            query[eq].v=x;            query[eq].w=i;            query[eq].next=gg[y];            gg[y]=eq;            eq++;            res[i][0]=x;            res[i][1]=y;        }        dis[1]=0;        tarjan(1);        for (int i=1; i<=m; i++)        {            cout<<dis[res[i][0]]+dis[res[i][1]]-2*dis[res[i][2]]<<endl;        }    }    return 0;}


0 0
原创粉丝点击