tarjan 离线 lca hdu2586

来源:互联网 发布:李佩谕新闻大数据 编辑:程序博客网 时间:2024/05/18 20:05

lca的离线操作:这篇博客写的很好 https://www.cnblogs.com/JVxie/p/4854719.html。。

我实现的代码

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int maxn=80010;struct node{    int v,next,w;}edge[maxn*2];int n;int head[maxn],dis[maxn],cnt,pre[maxn],ancestor[maxn],vis[maxn],answer[maxn];int ans[maxn];void init(){    memset(head,-1,sizeof(head));    memset(dis,0,sizeof(dis));    for(int i=1;i<=n;i++)    {        pre[i]=i;    }    cnt=0;    memset(vis,0,sizeof(vis));    memset(ancestor,0,sizeof(ancestor));}int find(int x){    int r=x;    while(r!=pre[r])        r=pre[r];    int i=x,j;    while(i!=r)    {        j=pre[i];        pre[i]=r;        i=j;    }    return r;}void bing(int x,int y){    int tx=find(x);    int ty=find(y);    if(tx!=ty)    {        pre[tx]=ty;    }}void add_edge(int u,int v,int w){    edge[cnt].v=v;    edge[cnt].next=head[u];    edge[cnt].w=w;    head[u]=cnt++;}struct query{    int v,index,next,u;}query_edge[maxn];int h[maxn],cc=0;void initt(){    memset(h,-1,sizeof(h));    cc=0;}void add_query(int u,int v,int index){    query_edge[cc].v=v;    query_edge[cc].u=u;    query_edge[cc].next=h[u];    query_edge[cc].index=index;    h[u]=cc++;}void lca(int u){    vis[u]=1;    ancestor[u]=u;    for(int i=head[u];i!=-1;i=edge[i].next)    {        int v=edge[i].v;        if(vis[v])            continue;        dis[v]=dis[u]+edge[i].w;        lca(v);        bing(u,v);        ancestor[find(u)]=u;    }    for(int i=h[u];i!=-1;i=query_edge[i].next)    {        int v=query_edge[i].v;        if(vis[v])        {            answer[query_edge[i].index]=dis[u]+dis[v]-dis[ancestor[find(v)]]*2;        }    }}int main (){    int t;    scanf("%d",&t);    while(t--)    {        int m;        scanf("%d%d",&n,&m);        init();        for(int i=1;i<n;i++)        {            int u,v,w;            scanf("%d%d%d",&u,&v,&w);            add_edge(u,v,w);            add_edge(v,u,w);        }        initt();        for(int i=1;i<=m;i++)        {            int u,v;            scanf("%d%d",&u,&v);            add_query(u,v,i);            add_query(v,u,i);        }        int num=0;        int flag[maxn];        int root;        for(int i = 1;i <= n;i++)            if(!flag[i])            {                root = i;                break;            }        lca(root);        for(int i=1;i<=m;i++)        {            printf("%d\n",answer[i]);        }    }}
原创粉丝点击