zoukankan      html  css  js  c++  java
  • 【HDOJ2586】【Tarjan离线求LCA】

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

    How far away ?

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


    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
    题目大意:给一个有权树,有Q次询问,求任意两点的距离。
    题目分析:在树中有一个性质:任意两点的距离 ANS = dist[ u ] + dist[ v ] - dist[ lca(u,v)  ],其中dist[ I ]是根到 I 的 距离 ,由于需要多次询问,所以使用Tarjan离线求LCA比较快
      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<queue>
      5 #include<vector>
      6 using namespace std;
      7 const int maxn=40005;
      8 struct edge{
      9     int to;
     10     int len;
     11 };
     12 vector<struct edge>G[maxn];
     13 vector<int>qury[maxn];
     14 vector<int>num[maxn];
     15 int dis[maxn],vis[maxn],ans[maxn],fa[maxn];
     16 void init()
     17 {
     18     memset(dis,0,sizeof(dis));
     19     memset(vis,0,sizeof(vis));
     20     for(int i = 0 ; i < 40005 ; i++)
     21     {
     22         G[i].clear();
     23         qury[i].clear();
     24         num[i].clear();
     25         fa[i]=i;
     26     }
     27 }
     28 int find(int x)
     29 {
     30     int xx=x;
     31     while(fa[x]!=x)
     32     {
     33         x=fa[x];
     34     }
     35     while(fa[xx]!=x)
     36     {
     37         int t=fa[xx];
     38         fa[xx]=x;
     39         xx=t;
     40     }
     41     return x;
     42 }
     43 void Union(int x,int y)
     44 {
     45     int xx=find(x);
     46     int yy=find(y);
     47     if(xx!=yy);
     48     fa[yy]=xx;//在完成子节点的Tarjan遍历之后,把子节点纳入父节点名下
     49 }
     50 void Tarjan(int u,int ll)
     51 {
     52     vis[u]=1;
     53     dis[u]=ll;
     54     for(int i = 0 ; i< G[u].size() ;i++)
     55     {
     56         struct edge wqw=G[u][i];
     57         if(vis[wqw.to])continue;
     58         Tarjan(wqw.to,wqw.len+ll);
     59         Union(u,wqw.to);
     60     }
     61     for(int i = 0 ; i < qury[u].size() ; i++)
     62     {
     63         if(vis[qury[u][i]])
     64         {
     65             ans[num[u][i]]=dis[u]+dis[qury[u][i]]-2*dis[find(qury[u][i])];    
     66         }
     67     }
     68 }
     69 int main()
     70 {
     71     int t;
     72     scanf("%d",&t);
     73     while(t--)
     74     {
     75         init();
     76         int n,m;
     77         scanf("%d%d",&n,&m);
     78         for(int i = 1 ; i < n ; i++)
     79         {
     80             int a,b,c;
     81             scanf("%d%d%d",&a,&b,&c);
     82             G[a].push_back((struct edge){b,c});
     83             G[b].push_back((struct edge){a,c});
     84         }
     85         for(int i = 0 ; i < m ; i++)
     86         {
     87             int a,b;
     88             scanf("%d%d",&a,&b);
     89             qury[a].push_back(b);
     90             qury[b].push_back(a);
     91             num[a].push_back(i);
     92             num[b].push_back(i);
     93         }
     94         Tarjan(1,0);
     95         for(int i = 0 ; i < m ; i++)
     96         {
     97             printf("%d
    ",ans[i]);
     98         }
     99     }
    100     return 0; 
    101 }
  • 相关阅读:
    win10系统安装oracle11g时遇到INS-13001环境不满足最低要求
    C#文件重命名的代码
    自学MVC开发基础
    我的面试感悟-----3年工作经验的女程序员的感慨
    问心无愧,莫问前程
    Install your Application into RaspberryPi2 and automatically start up
    基于Vmware player的Windows 10 IoT core + RaspberryPi2安装部署
    MVC开发-后台开发总结
    页面长按禁止弹出选择菜单
    js检测链接(URL)是否有效
  • 原文地址:https://www.cnblogs.com/MekakuCityActor/p/9048228.html
Copyright © 2011-2022 走看看