POJ1986(LCA应用:求两结点之间距离)

Distance Queries

Time Limit: 2000MS   Memory Limit: 30000K
Total Submissions: 11304   Accepted: 3985
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 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离线:将所有查询输入完毕后再统一输出结果。在线:查询一个输出一个。

dfs+并查集,离线
#include"cstdio"
#include"cstring"
#include"vector"
using namespace std;
typedef pair<int,int> P;
const int MAXN=100005;
int V,E;
vector<P> G[MAXN];
vector<P> que[MAXN];
int par[MAXN];
int fnd(int x)
{
    if(par[x]==x)
        return x;
    return par[x]=fnd(par[x]);
}
int vis[MAXN];
int ans[MAXN];
int d[MAXN];

void dfs(int u,int fa)
{
    par[u]=u;
    for(int i=0;i<que[u].size();i++)
    {
        P no=que[u][i];
        int v=no.first;
        if(vis[v])    ans[no.second]=d[u]+d[v]-2*d[fnd(v)];
    }
    vis[u]=1;
    for(int i=0;i<G[u].size();i++)
    {
        P now=G[u][i];
        if(now.first==fa)    continue;
        d[now.first]=d[u]+now.second;
        dfs(now.first,u);
        par[now.first]=u;
    }
}

int main()
{
    while(scanf("%d%d",&V,&E)!=EOF&&V)
    {
        for(int i=1;i<=V;i++)
        {
            G[i].clear();
            que[i].clear();
        }
        memset(vis,0,sizeof(vis));
        memset(ans,0,sizeof(ans));
        memset(d,0,sizeof(d));
        for(int i=0;i<E;i++)
        {
            int u,v,cost;
            scanf("%d %d %d %*c",&u,&v,&cost);
            G[u].push_back(P(v,cost));
            G[v].push_back(P(u,cost));
        }
        int Q;
        scanf("%d",&Q);
        for(int i=1;i<=Q;i++)
        {
            int u,v;
            scanf("%d%d",&u,&v);
            que[u].push_back(P(v,i));
            que[v].push_back(P(u,i));
        }
        dfs(1,-1);
        for(int i=1;i<=Q;i++)
        {
            printf("%d\n",ans[i]);
        }
    }

    return 0;
}
				
时间: 2024-12-29 11:47:44

POJ1986(LCA应用:求两结点之间距离)的相关文章

求两个数之间的随机正整数

求两个数之间的随机正整 数.并添到新数组,数组长度由自己指定.并且数组中不能有重复的值 function getRandomInt (min, max) { return Math.floor(Math.random() * (max - min + 1) + min) } function numInt(n, min, max) { const arr = [] while(arr.length < n) { let num = getRandomInt(min, max) if (arr.i

四棵树怎么种才能使任意两颗之间距离相等

1.从宏观来看,把这四颗树看成四个质点 第一种办法是把它们种在一起,这样两两之间距离都为0: 第二种办法是使它们形成一个三棱锥,比如可以在山顶种一棵树,在山脚分三个方位种三棵树:或者在坑底种一棵树,坑外面分别种三棵树. 2.从微观来看,这四颗树都是有形状的,那么重点就在于他们之间的“距离”怎么定义. 第一.如果这四颗树不是笔直(树干长歪了,考虑树冠.枝干和叶子)的话,那么需要根据它们具体的形状来给出具体的解决方案,有兴趣的同学可以由此开发一个仿生数学模型: 第二.如果这四颗树都是笔直的,那么它们

hdoj 1869 六度分离【最短路径求两两边之间最长边】

六度分离 Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5443    Accepted Submission(s): 2208 Problem Description 1967年,美国著名的社会学家斯坦利·米尔格兰姆提出了一个名为“小世界现象(small world phenomenon)”的著名假说,大意是说,任何2个素不相识的人中

求两日期之间的相隔天数(year,month,day)

主要思路理解部分看ppt #include<cstdio> int isRunNian(int year); int DiJiTian(int year,int month,int day); void swap(int *a,int *b); int main() { int year1,month1,day1; int year2,month2,day2; int sum=0; scanf("%d%d%d",&year1,&month1,&day

求两数之间关系的关键算法

输入整数a,输出结果s,其中s与a的关系是:s=a+aa+aaa+aaaa+aa...a,最后为a个a.例如a=2时,s=2+22=24. 注意:①使用循环结构语句实现.②a由键盘输入,且2 ≤ a ≤9 package seven; import java.util.Scanner; public class three { public static void main(String[] args) { int s=0; int s1=0; int s2=0; Scanner sc = ne

两经纬度之间的距离计算

以下是计算两经纬度之间距离的代码,分为:头文件.源代码和测试代码三部分.具体如下: 1 // LatLonDistanceDlg.h : 头文件 2 // 3 4 #pragma once 5 6 typedef struct 7 { 8 double dLongitude; 9 double dLatitude; 10 }MyLatLong_T,*pMyLatLong_T; 11 12 // CLatLonDistanceDlg 对话框 13 class CLatLonDistanceDlg

求二叉树的给定两个结点之间的距离

给定一颗二叉树,和两个给定的结点,求出这两个结点之间的距离 拿到题目时不要认为是求出二叉树的结点之间的最大距离,题目是求两个结点的之间的距离 题目有几种情况 两个结点分布在根节点的左子树或者右子树 一个结点分布在根节点的左子树,一个结点分布在根节点的右子树 这两个结点是兄弟结点 一个结点是另外结点的祖先结点 本题的解题思路是 利用层次遍历的方法,获取每个结点的高度,根节点左子树的高度用正数表示,根节点右子树的高度用负数表示 这样当两个结点分布在:一个结点分布在根节点的左子树,一个结点分布在根节点

求二叉树中任意两个结点的距离

求二叉树中任意两个结点的距离 实现步骤: 计算跟到第一个结点的距离: 计算跟到第二个结点的距离: 计算lca: 计算跟到lca结点的距离: 结果为(1) + (2) - 2 * (4),因为重复计算了两次的从跟到lca结点的距离: 1 class Node(object): def __init__(self, value=0): self.value = value self.left = self.right = None def get_path_length(root, n, path)

二叉树中两个结点的距离

问题 对于普通的二叉树,如何找到两个给定节点之间的距离?距离是指连接两个节点所需要的最小边的条数. 例如下面的二叉树: 这个问题很全面的考察了二叉树的相关的知识,建议大家先尝试自己解决 分析: 假设给定的节点为node1,node2,可以分为下面的两种情况: 1)node1是node2的祖先节点或孩子结点,可以理解为两个节点在一条线上.例如:Dist(2,4),Dist(6,1) 2)node1和node2没有直接或间接的父子关系.例如,Dist(4,3),他们需要一个共同的祖先结点1连接起来