• HDU 2586 LCA


    最近公共祖先

    dis[a,b]  =  dis[1,a]+dis[1,b]-2*dis[1,lca[a,b]];

    #include<stdio.h>
    #include<algorithm>
    #include<string.h>
    #include<string>
    #include<vector>
    #include<queue>
    #include<iostream>
    #include<deque>
    using namespace std;
    
    #define inf 1000000000
    #define MAXN  40010
    
    struct edge
    {
        int fr,to,w,next;
    }edg[MAXN*2],edg1[MAXN];
    int cnt,tot;
    int head[MAXN],head1[MAXN];
    bool vis[MAXN];
    void add(int u,int v,int w)
    {
        edg[cnt].fr=u;
        edg[cnt].to=v;
        edg[cnt].w=w;
        edg[cnt].next=head[u];
        head[u]=cnt++;
    }
    void add1(int u,int v,int w)
    {
        edg1[tot].next=head1[u];
        edg1[tot].to=v;
        edg1[tot].fr=u;
        edg1[tot].w=w;
        head1[u]=tot++;
    }
    
    int dis[MAXN],lca[MAXN],fa[MAXN];
    
    int find1(int a)
    {
        if(a==fa[a])
            return a;
        else
        {
            int b=find1(fa[a]);
            return fa[a]=b;
        }
    }
    void tarjan(int u)
    {
      //  printf("1");
        vis[u]=1;
        fa[u]=u;
        for(int i=head1[u];i!=-1;i=edg1[i].next)
        {
            int v=edg1[i].to;
            if(vis[v])
                lca[edg1[i].w]=find1(v);
        }
        for(int i=head[u];i!=-1;i=edg[i].next)
        {
            int v=edg[i].to;
            if(!vis[v])
            {
                dis[v]=dis[u]+edg[i].w;
                tarjan(v);
                fa[v]=u;
            }
        }
    }
    int main()
    {
        int t;
        scanf("%d",&t);
        while(t--)
        {
            int n,m;
            scanf("%d%d",&n,&m);
            memset(head,-1,sizeof(head));
            cnt=0;
            for(int i=1;i<n;i++)
            {
                int u,v,w;
                scanf("%d%d%d",&u,&v,&w);
                add(u,v,w);
                add(v,u,w);
            }
            tot=0;
            memset(vis,0,sizeof(vis));
            memset(head1,-1,sizeof(head1));
            for(int i=1;i <= m;i++)  //离线算法  记录下这2个点查询的排名
            {
                int a,b;
                scanf("%d%d",&a,&b);
                add1(a,b,i);
                add1(b,a,i);
            }
            dis[1]=0;
            tarjan(1);
            for(int i=0;i<tot;i+=2)
            {
                int a,b,c;
                a=edg1[i].fr;
                b=edg1[i].to;
                c=edg1[i].w;
                printf("%d
    ",dis[a]+dis[b]-2*dis[lca[c]]);
            }
            //printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    Java中抽象类和接口的区别
    servlet的转发与重定向
    JSP知识点
    过滤器与拦截器
    java关键字 super 和 this
    oracle 基础
    java 集合
    java 内部类
    java 数组详解
    图,深度优先遍历与广度优先遍历
  • 原文地址:https://www.cnblogs.com/cherryMJY/p/6472081.html
Copyright © 2020-2023  润新知