POJ 1986 Distance Queries LCA

来源:互联网 发布:2016淘宝店开店流程 编辑:程序博客网 时间:2024/05/23 00:10

     带边权的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;}


0 0
原创粉丝点击