hdu 2586 How far away ?

http://acm.hdu.edu.cn/showproblem.php?pid=2586

在lca的基础上维护一下距离   维护是在并查集里进行的

代码:

#include <iostream>

#include <cstdio>

#include <string>

#include <cstring>

#include <algorithm>

#include <map>

#include <vector>

#include <set>

#include <stack>

#include <queue>

#pragma comment(linker, "/STACK:1024000000,1024000000")



using namespace std;



const int N=100005;

const int M=N*2;

int head[N],I;

struct node

{

    int j,next,d;

}edge[M];

struct question

{

    int l,r,lca,dist;

}q[N];

bool visited[N];

int f[N],d[N];

vector<int>vt[N],vtd[N];

int fx(int x)

{

    if(f[x]!=x)

    {

        int tmp=f[x];

        f[x]=fx(f[x]);

        d[x]+=d[tmp];

    }

    return f[x];

}

void add(int i,int j,int d)

{

    edge[I].j=j;

    edge[I].d=d;

    edge[I].next=head[i];

    head[i]=I++;

}

void init(int n,int m)

{

    for(int i=0;i<=n;++i)

    {vt[i].clear();vtd[i].clear();}

    memset(head,-1,sizeof(head));I=0;

    for(int i=1;i<n;++i)

    {

        int l,r,d;

        scanf("%d %d %d",&l,&r,&d);

        add(l,r,d);

        add(r,l,d);

    }

    for(int i=1;i<=m;++i)

    {

        scanf("%d %d",&q[i].l,&q[i].r);

        if(q[i].l==q[i].r)

        {q[i].lca=q[i].l;q[i].dist=0;continue;}

        q[i].lca=-1;

        q[i].dist=-1;

        vt[q[i].l].push_back(i);

        vt[q[i].r].push_back(i);

    }

}

void findLca(int x)

{

    for(unsigned int i=0;i<vt[x].size();++i)

    {

        int w=vt[x][i];

        int k;

        if(q[w].l==x) k=q[w].r;

        else k=q[w].l;

        if(visited[k]==true)

        {

            q[w].lca=fx(k);

            vtd[q[w].lca].push_back(w);

        }

    }

}

void findDist(int x)

{

    for(unsigned int i=0;i<vtd[x].size();++i)

    {

        int w=vtd[x][i];

        fx(q[w].l);fx(q[w].r);

        q[w].dist=d[q[w].l]+d[q[w].r];

    }

}

void dfs(int x,int pre,int L)

{

    visited[x]=true;

    f[x]=x;

    d[x]=0;

    findLca(x);

    for(int t=head[x];t!=-1;t=edge[t].next)

    {

        int j=edge[t].j;

        if(visited[j]==false)

        dfs(j,x,edge[t].d);

    }

    findDist(x);

    f[x]=pre;

    d[x]=L;

}

void lca(int n,int m)

{

    for(int i=0;i<=n;++i) f[i]=i;

    memset(visited,false,sizeof(visited));

    dfs(1,1,0);

}

int main()

{

    //freopen("data.in","r",stdin);

    int T;

    scanf("%d",&T);

    while(T--)

    {

        int n,m;

        scanf("%d %d",&n,&m);

        init(n,m);

        lca(n,m);

        for(int i=1;i<=m;++i)

        printf("%d\n",q[i].dist);

    }

}

  

你可能感兴趣的:(HDU)