• hdu 5286 How far away ? tarjan/lca


    How far away ?

    Time Limit: 20 Sec

    Memory Limit: 256 MB

    题目连接

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

    Description

    There are n houses in the village and some bidirectional roads connecting them. Every day peole always like to ask like this "How far is it if I want to go from house A to house B"? Usually it hard to answer. But luckily int this village the answer is always unique, since the roads are built in the way that there is a unique simple path("simple" means you can't visit a place twice) between every two houses. Yout task is to answer all these curious people.

    Input

    First line is a single integer T(T<=10), indicating the number of test cases.
      For each test case,in the first line there are two numbers n(2<=n<=40000) and m (1<=m<=200),the number of houses and the number of queries. The following n-1 lines each consisting three numbers i,j,k, separated bu a single space, meaning that there is a road connecting house i and house j,with length k(0<k<=40000).The houses are labeled from 1 to n.
      Next m lines each has distinct integers i and j, you areato answer the distance between house i and house j.

    Output

    For each test case,output m lines. Each line represents the answer of the query. Output a bland line after each test case.

    Sample Input

    2
    3 2
    1 2 10
    3 1 15
    1 2
    2 3

    2 2
    1 2 100
    1 2
    2 1

    Sample Output

    10
    25
    100
    100

    HINT

    题意

    题解:

    tarjan离线算法

    代码:

    # include<stdio.h>
    # include<string.h>
    # define N 40005
    # define M 205
    struct node{
        int from,to,next,val;
    }edge[2*N];
    struct node1{
        int from,to,next,num;
    }edge1[2*M];
    int tol,head[N],head1[N],tol1,father[N],dis[N],LCA[M],n,m;
    bool visit[N];
    void add(int a,int b,int c)
    {
        edge[tol].from=a;edge[tol].to=b;edge[tol].next=head[a];edge[tol].val=c;head[a]=tol++;
    }
    void add1(int a,int b,int c)
    {
        edge1[tol1].from=a;edge1[tol1].to=b;edge1[tol1].next=head1[a];edge1[tol1].num=c;head1[a]=tol1++;
    }
    int find(int x)
    {
        if(x!=father[x])
            father[x]=find(father[x]);
        return father[x];
    }
    void tarjan(int u)
    {
        int j,v;
        visit[u]=1;
        father[u]=u;
        //////////////////
        for(j=head1[u];j!=-1;j=edge1[j].next)
        {
            v=edge1[j].to;
            if(visit[v]) LCA[edge1[j].num]=find(v);
        }
        //////////////////
        for(j=head[u];j!=-1;j=edge[j].next)
        {
            v=edge[j].to;
            if(!visit[v]) 
            {
                dis[v]=dis[u]+edge[j].val;
                tarjan(v);
                father[v]=u;
            }
        }
    }
    int main()
    {
        int i,ncase,a,b,c;
        scanf("%d",&ncase);
        while(ncase--)
        {
            scanf("%d%d",&n,&m);
            tol=0;
            memset(head,-1,sizeof(head));
            for(i=1;i<n;i++)
            {
                scanf("%d%d%d",&a,&b,&c);
                add(a,b,c);
                add(b,a,c);
            }
            memset(visit,0,sizeof(visit));
            tol1=0;
            memset(head1,-1,sizeof(head1));
            for(i=1;i<=m;i++)
            {
                scanf("%d%d",&a,&b);
                add1(a,b,i);
                add1(b,a,i);
            }
            ///LCA是一种离线算法,所以刚开始需要把所有的询问都输入,然后用邻接表进行存储,i表示第i次询问
            dis[1]=0;
            tarjan(1);
            for(i=0;i<tol1;i+=2)
            {
                a=edge1[i].from;
                b=edge1[i].to;
                c=edge1[i].num;
                printf("%d
    ",dis[a]+dis[b]-2*dis[LCA[c]]);
            }
        }
        return 0;
    }
  • 相关阅读:
    在多租户(容器)数据库中如何创建PDB:方法6 DBCA本地克隆PDB
    在多租户(容器)数据库中如何创建PDB:方法5 DBCA远程克隆PDB
    1级搭建类104-Oracle 12cR2 单实例 FS(阿里云)公开
    在多租户(容器)数据库中如何创建PDB:方法4 克隆远程Non-CDB
    在多租户(容器)数据库中如何创建PDB:方法3 克隆远程PDB
    番外:克隆本地PDB中其他参数和子句的说明
    在多租户(容器)数据库中如何创建PDB:方法2 克隆本地PDB
    Oracle Solaris 10 重启后提示 Bad PBR sig
    在多租户(容器)数据库中如何创建PDB:方法1 从种子创建PDB
    0级搭建类009-Fedora 30 安装(F30) 公开
  • 原文地址:https://www.cnblogs.com/qscqesze/p/4563307.html
Copyright © 2020-2023  润新知