zoukankan      html  css  js  c++  java
  • hdu 2583 How far away ? 离线算法 带权求最近距离

    How far away ?

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 28961    Accepted Submission(s): 11639


    Problem 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
     
    题目大意:给一个n个节点的带权树,m次询问,求两点之间的距离
    第一行输入t,表示多个测试样例
    第二行输入n,m,表示n个节点和m次询问
    接下来n-1行,每行输入x,y,w,表示x到y的距离为w
    最后m行每行输入两个数xx,yy,询问xx到yy的最短距离为多少
     
    这题给人的感觉就是最短路可以做,但是注意数据范围40000,开不了40000的二维数组,所以直接gg
    但其实就是简单的最近公共祖先问题,找到x,y两点最近的公共祖先节点z[i],dis[x]+dis[y]-2*dis[z[i]]就是答案
     
     
    #include<iostream>
    #include<string.h>
    #include<vector>
    using namespace std;
    struct node
    {
        int id;
        int len;
    }p;
    vector<node>mp[40005];//结构体动态数组
    int dis[40005],xx[40005],yy[40005],vis[40005],z[40005],fa[40005];//dis是存距离,xx,yy存询问的点,z[i]表示i的LCA是点z[i],fa是存父亲节点
    int t,n,m;
    void add(int a,int b,int c)//加边建树
    {
        p.id=b;
        p.len=c;
        mp[a].push_back(p);
    }
    void init()//初始化
    {
        for(int i=1;i<=n;i++)
        {
            fa[i]=i;
            mp[i].clear();
            dis[i]=0;
            vis[i]=0;
            z[i]=0;
        }
    }
    int find(int x)
    {
        if(fa[x]!=x)
            return fa[x]=find(fa[x]);
        return fa[x];
    
    }
    
    void join(int x,int y)
    {
        x=find(x);
        y=find(y);
        if(x!=y)
            fa[y]=x;
    }
    void tarjan(int x)
    {
        vis[x]=1;
        for(int i=0;i<mp[x].size();i++)
        {
            int y=mp[x][i].id;
            if(!vis[y])//未遍历过
            {
                dis[y]=dis[x]+mp[x][i].len;//更新距离
                tarjan(y);//遍历下一个点
                join(x,y);//合并
            }
            
    
        }
        for(int i=1;i<=m;i++)
        {
            if(xx[i]==x&&vis[yy[i]])
                z[i]==find(yy[i]);
            if(yy[i]==x&&vis[xx[i]])
                z[i]=find(xx[i]);
        }
    
    }
    int main()
    {
        cin>>t;
        while(t--)
        {
            cin>>n>>m;
            int a,b,c;
            init();
            for(int i=1;i<n;i++)//描述边
            {
                cin>>a>>b>>c;
                add(a,b,c);
                add(b,a,c);
            }
            for(int i=1;i<=m;i++)//询问
            {
                cin>>xx[i]>>yy[i];
            }
            tarjan(1);
            for(int i=1;i<=m;i++)
                cout<<dis[xx[i]]+dis[yy[i]]-2*dis[z[i]]<<endl;
        }
        return 0;
    }
  • 相关阅读:
    poi操作excel2007(读取、生成、编辑)
    poi API大全
    iText导出pdf、word、图片
    正则表达式判断是否是中国电信的号码
    正则表达式_判断金额是否为数字(且是2位有效数字)
    POI实现Excel2003插入多张图片
    java中BufferedReader 有什么用
    poi生成word2007及以上文件
    POI 详细介绍
    GDB之常见错误
  • 原文地址:https://www.cnblogs.com/-citywall123/p/11065033.html
Copyright © 2011-2022 走看看