zoukankan      html  css  js  c++  java
  • 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
    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;
            }
        }
    }
     
  • 相关阅读:
    sql取每个分组的第一行数据
    PHP microtime() 函数
    笔记产品会不会被淘汰
    making an os NO.1 怎样进内核之二
    hjkhjkh
    HTTP协议理解
    hjkhjkh
    making an os NO.1 怎样进内核之一
    hjkhjkh
    笔记产品会不会被淘汰
  • 原文地址:https://www.cnblogs.com/Aa1039510121/p/6657911.html
Copyright © 2011-2022 走看看