首页 > 代码库 > hdu 2586(Tarjan 离线算法)

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;
        }
    }
}

 

 

hdu 2586(Tarjan 离线算法)