hdu 2586(Tarjan 离线算法)

How far away ?

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

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

Source

ECJTU 2009 Spring Contest

LCA离线做法的板子  Tarjan算法(DFS+并查集)

不想解释  我就想贴个板子

#include<iostream>
#include<cstdio>
#include<cmath>
#include<map>
#include<cstdlib>
#include<vector>
#include<set>
#include<queue>
#include<cstring>
#include<string.h>
#include<algorithm>
typedef long long ll;
typedef unsigned long long LL;
using namespace std;
const int N=40000+100;
int head[N];
int vis[N];
int parent[N];
int ans[N];
int cnt;
vector<int>q[N];
vector<int>Q[N];
int dis[N];
int n;
int ancestor[N];
struct node{
    int to,next,w;
}edge[2*N+10];
void init(){
    cnt=0;
    memset(ans,0,sizeof(ans));
    memset(dis,0,sizeof(dis));
    memset(head,-1,sizeof(head));
    memset(vis,0,sizeof(vis));
    for(int i=0;i<=n;i++){
        parent[i]=i;
        Q[i].clear();
        q[i].clear();
    }
}
void add(int u,int v,int w){
    edge[cnt].to=v;
    edge[cnt].w=w;
    edge[cnt].next=head[u];
    head[u]=cnt++;
}
int find(int x){
    int r=x;
    while(r!=parent[x])r=parent[r];
    int i=x;
    int j;
    while(parent[i]!=r){
        j=parent[i];
        parent[i]=r;
        i=j;
    }
    return r;
}
void Union(int x,int y){
    x=find(x);
    y=find(y);
    if(x!=y)parent[y]=x;
}
void Tarjan(int x,int w){
    vis[x]=1;
    dis[x]=w;
    //cout<<dis[x]<<endl;
    for(int i=head[x];i!=-1;i=edge[i].next){
        int v=edge[i].to;
        if(vis[v])continue;
        Tarjan(v,w+edge[i].w);
        Union(x,v);
        ancestor[find(x)]=x;
    }
    for(int i=0;i<q[x].size();i++){
        int u=q[x][i];
        if(vis[u]){
            int t=ancestor[find(u)];
            ans[Q[x][i]]=dis[x]+dis[u]-dis[t]*2;
        }
    }
}
int main(){
    int m;
    int t;
    scanf("%d",&t);
    while(t--){
        init();
        scanf("%d%d",&n,&m);
        int u,v,w;
        for(int i=0;i<n-1;i++){
            scanf("%d%d%d",&u,&v,&w);
            add(u,v,w);
            add(v,u,w);
        }
        for(int i=0;i<m;i++){
            scanf("%d%d",&u,&v);
            q[u].push_back(v);
            q[v].push_back(u);
            Q[u].push_back(i);
            Q[v].push_back(i);
        }
        Tarjan(1,0);
       // for(int i=1;i<=n;i++)cout<<dis[i]<<" ";
        //cout<<endl;
        for(int i=0;i<m;i++){
               // cout<<4<<endl;
            cout<<ans[i]<<endl;
        }
    }
}
时间: 2024-08-25 00:44:45

hdu 2586(Tarjan 离线算法)的相关文章

HDU 2586 LCA离线算法 tarjan算法

LCA tarjan算法模板题 题意:给一个无根树,有q个询问,每个询问两个点,问两点的距离. 用tarjan离线算法算出每个询问的两点的最近公共祖先 ans[i]=dis[x[i]]+dis[y[i]]-2*dis[z[i]]; //  x[i],y[i]分别存储每次询问的两点,z[i]存储这两点的最近公共祖先 #include "stdio.h" #include "string.h" int tot,n,m; int f[40010],x[40010],y[4

LCA(最近公共祖先)--tarjan离线算法 hdu 2586

HDU 2586 How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 11320    Accepted Submission(s): 4119 Problem Description There are n houses in the village and some bidirectional roads c

HDU 2586 How Far Away?(Tarjan离线算法求lca)

题意:给定一棵树n个节点m个询问,每次询问两个节点之间的距离. 思路:Tarjan离线算法求lca. 这题一开始交了n发一直爆栈.......百度了一下大概说的是这样hdu用的是windows服务器所以栈大小极其坑爹,稍微深一点的递归就会爆栈(正式比赛一般不会爆) 解决方法就是加一句#pragma comment(linker, "/STACK:1024000000,1024000000") 用c++交就好.....当然这只是针对比较坑爹oj来说的取巧的方法 #include<c

HDU 2874 LCA离线算法

Connections between cities Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4477    Accepted Submission(s): 1284 Problem Description After World War X, a lot of cities have been seriously damage

笔记:LCA最近公共祖先 Tarjan(离线)算法

LCA最近公共祖先 Tarjan他贱(离线)算法的基本思路及其算法实现 本文是网络资料整理或部分转载或部分原创,参考文章如下: https://www.cnblogs.com/JVxie/p/4854719.html http://blog.csdn.net/ywcpig/article/details/52336496 https://baike.baidu.com/item/最近公共祖先/8918834?fr=aladdin 最近公共祖先简称LCA(Lowest Common Ancesto

[图论] LCA(最近公共祖先)Tarjan 离线算法

很好的参考资料:http://taop.marchtea.com/04.04.html    下面的配图和部分文字转载于此文章 离线算法就是指统一输入后再统一输出,而不是边输入边实时输出.Tarjan算法的复杂度为O(N+Q),Q为询问的次数. 由于是离线算法,所以要保存输入的信息,次序问题. 若两个结点u.v分别分布于某节点t 的左右子树,那么此节点 t即为u和v的最近公共祖先.更进一步,考虑到一个节点自己就是LCA的情况,得知: ?若某结点t 是两结点u.v的祖先之一,且这两结点并不分布于该

【C++】最近公共祖先LCA(Tarjan离线算法)&amp;&amp; 洛谷P3379LCA模板

1.前言 首先我们介绍的算法是LCA问题中的离线算法-Tarjan算法,该算法采用DFS+并查集,再看此算法之前首先你得知道并查集(尽管我相信你如果知道这个的话肯定是知道并查集的),Tarjan算法的优点在于相对稳定,时间复杂度也比较居中,也很容易理解(个人认为). 2.思想 下面详细介绍一下Tarjan算法的思想: 1.任选一个点为根节点,从根节点开始. 2.遍历该点u所有子节点v,并标记这些子节点v已被访问过. 3.若是v还有子节点,返回2,否则下一步. 4.合并v到u上. 5.寻找与当前点

POJ 1330 Nearest Common Ancestors 【最近公共祖先LCA算法+Tarjan离线算法】

Nearest Common Ancestors Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 20715   Accepted: 10910 Description A rooted tree is a well-known data structure in computer science and engineering. An example is shown below: In the figure, each

HDU ACM 2586 How far away ?LCA-&amp;gt;并查集+Tarjan(离线)算法

题意:一个村子有n个房子,他们用n-1条路连接起来,每两个房子之间的距离为w.有m次询问,每次询问房子a,b之间的距离是多少. 分析:近期公共祖先问题,建一棵树,求出每一点i到树根的距离d[i],每次询问a.b之间的距离=d[a]+d[b]-2*d[LCA(a,b)];LCA(a,b)是a,b的近期公共祖先. #pragma comment(linker, "/STACK:1024000000,1024000000") #include<iostream> #include