POJ 1986 Distance Queries LCA

     带边权的LCA,记录Dis[x]为根到x的距离,有dis[x,y]=dis[x]+dis[y]-2*dis[lca(x,y)]。

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

        int x,y,z;
        char ttt[4];
        for (int i=1; i<=m; i++)
        {
            scanf("%d%d%d",&x,&y,&z);
            scanf("%s",ttt);
            edge[en].v=y;
            edge[en].w=z;
            edge[en].next=g[x];
            g[x]=en;
            en++;

            edge[en].v=x;
            edge[en].w=z;
            edge[en].next=g[y];
            g[y]=en;
            en++;
        }
        scanf("%d",&k);
        for (int i=1; i<=k; i++)
        {
            scanf("%d%d",&x,&y);
            q[eq].v=y;
            q[eq].w=i;
            q[eq].next=gg[x];
            gg[x]=eq;
            eq++;

            q[eq].v=x;
            q[eq].w=i;
            q[eq].next=gg[y];
            gg[y]=eq;
            eq++;
            res[i][0]=x;
            res[i][1]=y;
        }
        dis[0]=0;
        tarjan(1);
        for (int i=1; i<=k; i++)
        cout<<dis[res[i][0]]+dis[res[i][1]]-(dis[res[i][2]]<<1)<<endl;
    }
    return 0;
}


你可能感兴趣的:(POJ 1986 Distance Queries LCA)