POJ_1986_Distance Queries(LCA+tarjan)

Distance Queries

Time Limit: 2000MS   Memory Limit: 30000KB   64bit IO Format: %I64d & %I64u

Submit
Status

Description

Farmer John‘s cows refused to run in his marathon since he chose a path much too long for their leisurely lifestyle. He therefore wants to find a path of a more reasonable length. The input to this problem consists of the same
input as in "Navigation Nightmare",followed by a line containing a single integer K, followed by K "distance queries". Each distance query is a line of input containing two integers, giving the numbers of two farms between which FJ is interested in computing
distance (measured in the length of the roads along the path between the two farms). Please answer FJ‘s distance queries as quickly as possible!

Input

* Lines 1..1+M: Same format as "Navigation Nightmare"

* Line 2+M: A single integer, K. 1 <= K <= 10,000

* Lines 3+M..2+M+K: Each line corresponds to a distance query and contains the indices of two farms.

Output

* Lines 1..K: For each distance query, output on a single line an integer giving the appropriate distance.

Sample Input

7 6
1 6 13 E
6 3 9 E
3 5 7 S
4 1 3 N
2 4 20 W
4 7 2 S
3
1 6
1 4
2 6

Sample Output

13
3
36

题意:在一棵树上,查询(u,v)最短距离。

分析:LCA+tarjan离线算法,模板题。

ps:最近写LCA用的都是数组来存边,感觉比vector好用多了~~~~~

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=11131

代码清单:

//#pragma comment(linker, "/STACK:102400000,102400000")
#include<set>
#include<map>
#include<cmath>
#include<queue>
#include<stack>
#include<ctime>
#include<string>
#include<cstdio>
#include<cstring>
#include<cctype>
#include<cstdlib>
#include<iostream>
#include<algorithm>
using namespace std;

typedef long long ll;
typedef unsigned int uint;
typedef unsigned long long ull;

const int maxn = 40000 + 5;
const int maxv = 40000 + 5;
const int maxq = 10000 + 5;

struct MAX{
    int v,d;
    MAX(){}
    MAX(int v,int d){
        this -> v = v;
        this -> d = d;
    }
};

struct Q{ int v,id,next; }quary[2*maxq];
struct e{ int v,dis,next; }graph[2*maxn];
int n,m,q;
int a,b,c;
char s[3];
int father[maxn];
bool vis[maxn];
int ans[maxq];
int color[maxn];
int depth[maxn];
int nume,numq;
int heade[maxn];
int headq[maxn];

void init(){
    for(int i=1;i<=maxn;i++) father[i]=i;
    memset(ans,-1,sizeof(ans));
    memset(color,0,sizeof(color));
    memset(depth,0,sizeof(depth));
    memset(vis,false,sizeof(vis));
    memset(graph,0,sizeof(graph));
    memset(quary,0,sizeof(quary));
    memset(heade,-1,sizeof(heade));
    memset(headq,-1,sizeof(headq));
    nume=numq=0;
}

void add_E(int u,int v,int dis){
    graph[nume].v=v;
    graph[nume].dis=dis;
    graph[nume].next=heade[u];
    heade[u]=nume++;
}

void add_Q(int u,int v,int id){
    quary[numq].v=v;
    quary[numq].id=id;
    quary[numq].next=headq[u];
    headq[u]=numq++;
}

void input(){
    for(int i=0;i<m;i++){
        scanf("%d%d%d%s",&a,&b,&c,s);
        add_E(a,b,c);
        add_E(b,a,c);
    }
    scanf("%d",&q);
    for(int i=1;i<=q;i++){
        scanf("%d%d",&a,&b);
        add_Q(a,b,i);
        add_Q(b,a,i);
    }
}

int Find(int x){ return x!=father[x] ? father[x]=Find(father[x]) : father[x]; }

void tarjan(int u){
    color[u]=1;
    vis[u]=true;
    for(int i=headq[u];i!=-1;i=quary[i].next){
        int ID=quary[i].id;
        if(ans[ID]!=-1) continue;
        int v=quary[i].v;
        if(color[v]==0) continue;
        if(color[v]==1) ans[ID]=depth[u]-depth[v];
        if(color[v]==2) ans[ID]=depth[u]+depth[v]-2*depth[Find(v)];
    }
    for(int i=heade[u];i!=-1;i=graph[i].next){
        int vv=graph[i].v;
        int dis=graph[i].dis;
        if(!vis[vv]){
            depth[vv]=depth[u]+dis;
            tarjan(vv);
            color[vv]=2;
            father[vv]=u;
        }
    }
}

void solve(){
    tarjan(1);
    for(int i=1;i<=q;i++){
        printf("%d\n",ans[i]);
    }
}

int main(){
    while(scanf("%d%d",&n,&m)!=EOF){
        init();
        input();
        solve();
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-13 07:31:51

POJ_1986_Distance Queries(LCA+tarjan)的相关文章

HDU_2586 &amp;&amp; HDU_2874 (LCA+tarjan)

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

ZOJ_3195_Design the city(LCA+tarjan)

Design the city Time Limit: 1000MS   Memory Limit: 32768KB   64bit IO Format: %lld & %llu Submit Status Description Cerror is the mayor of city HangZhou. As you may know, the traffic system of this city is so terrible, that there are traffic jams eve

POJ1986 Distance Queries (LCA)

传送门: http://poj.org/problem?id=1986 Distance Queries Time Limit: 2000MS   Memory Limit: 30000K       Case Time Limit: 1000MS Description Farmer John's cows refused to run in his marathon since he chose a path much too long for their leisurely lifesty

POJ 1986 Distance Queries LCA树上两点的距离

题目来源:POJ 1986 Distance Queries 题意:给你一颗树 q次询问 每次询问你两点之间的距离 思路:对于2点 u v dis(u,v) = dis(root,u) + dis(root,v) - 2*dis(roor,LCA(u,v)) 求最近公共祖先和dis数组 #include <cstdio> #include <cstring> #include <vector> using namespace std; const int maxn =

最近公共祖先LCA(Tarjan算法)的思考和算法实现——转载自Vendetta Blogs

最近公共祖先LCA(Tarjan算法)的思考和算法实现 LCA 最近公共祖先 Tarjan(离线)算法的基本思路及其算法实现 小广告:METO CODE 安溪一中信息学在线评测系统(OJ) //由于这是第一篇博客..有点瑕疵...比如我把false写成了flase...看的时候注意一下! //还有...这篇字比较多 比较杂....毕竟是第一次嘛 将就将就 后面会重新改!!! 首先是最近公共祖先的概念(什么是最近公共祖先?): 在一棵没有环的树上,每个节点肯定有其父亲节点和祖先节点,而最近公共祖先

hihoCoder #1067 : 最近公共祖先&#183;二 [ 离线LCA tarjan ]

传送门: #1067 : 最近公共祖先·二 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 上上回说到,小Hi和小Ho用非常拙劣——或者说粗糙的手段山寨出了一个神奇的网站,这个网站可以计算出某两个人的所有共同祖先中辈分最低的一个是谁.远在美国的他们利用了一些奇妙的技术获得了国内许多人的相关信息,并且搭建了一个小小的网站来应付来自四面八方的请求. 但正如我们所能想象到的……这样一个简单的算法并不能支撑住非常大的访问量,所以摆在小Hi和小Ho面前的无非两种选择: 其一是

HDU 2586 How far away ? (离线LCA Tarjan算法模板)

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

【LCA/tarjan】POJ1470-Closest Common Ancestors

[题意] 给出一棵树和多组查询,求以每个节点为LCA的查询数有多少? [错误点] ①读入的时候,注意它的空格是随意的呀!一开始不知道怎么弄,后来看了DISCUSS区大神的话: 询问部分输入: scanf("%d",&m); for(int i=0;i<m;i++){ scanf(" (%d %d)",&a,&b); } 注意scanf(" 这里有一个空格 ②多组数据啊!注意这句话:The input file contents

hdu-2874 Connections between cities(lca+tarjan+并查集)

题目链接: Connections between cities Time Limit: 10000/5000 MS (Java/Others)     Memory Limit: 32768/32768 K (Java/Others) Problem Description After World War X, a lot of cities have been seriously damaged, and we need to rebuild those cities. However, s