Hdoj 2586 How far away ? 【LCA】

How far away ?

Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)

Total Submission(s): 7072 Accepted Submission(s): 2575

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

#include <cstdio>
#include <iostream>
#include <vector>
const int M = 4e4+5;
using namespace std;

struct node{
    int to, val;
};

vector<node > map[M];
vector<int> q[M], num[M];
bool vis[M];
int dis[M], ans[300], fat[M];

int f(int x){
    if(x != fat[x]) fat[x] = f(fat[x]);
    return fat[x];
}

void Lca(int u){
    vis[u] = 1;
    for(int i = 0; i < map[u].size(); ++i){
        int v = map[u][i].to;
        if(!vis[v]){
            dis[v] = dis[u]+map[u][i].val;
            Lca(v);
            fat[v] = u;
        }
    }
    for(int i = 0; i < q[u].size(); ++ i){
        int v = q[u][i];
        if(vis[v]){
            ans[num[u][i]] = dis[u]+dis[v]-2*dis[f(v)];
        }
    }
}

int main(){
    int t, n, m;
    //ios::sync_with_stdio(false);
    scanf("%d", &t);
    while(t --){
      scanf("%d%d", &n, &m);
      for(int i = 1; i <= n; ++ i){
        map[i].clear(); q[i].clear();
        fat[i] = i; vis[i] = 0;
      }
      int a, b, c;
      for(int i = 0; i < n-1; ++i){
        scanf("%d%d%d", &a, &b, &c);
        node temp;
        temp.to = a; temp.val = c;
        map[b].push_back(temp);
        temp.to = b;
        map[a].push_back(temp);
      }
      for(int i = 0; i < m; ++i){
        scanf("%d%d", &a, &b);
        q[a].push_back(b);
        q[b].push_back(a);
        num[a].push_back(i);
        num[b].push_back(i);
      }
      //memset(vis, 0, sizeof(vis));
      dis[1] = 0;
      Lca(1);
      for(int i = 0; i < m; ++ i) printf("%d\n", ans[i]);
    }
    return 0;
}

附RE代码:

#include <cstdio>
#include <iostream>
#include <vector>
const int M = 4e4+5;
using namespace std;

struct node{
    int to, val;
};

vector<node > map[M];
vector<int> q[M], num[M];
bool vis[M];
int dis[M], ans[300], fat[M];

int f(int x){
    if(x != fat[x]) fat[x] = f(fat[x]);
    return fat[x];
}

void Lca(int u, int cur){ //就是这里多了一个参数,溢出了。。
    vis[u] = 1;
    dis[u] = cur;
    for(int i = 0; i < map[u].size(); ++i){
        int v = map[u][i].to;
        if(!vis[v]){
            Lca(v, cur+map[u][i].val);
            fat[v] = u;
        }
    }
    for(int i = 0; i < q[u].size(); ++ i){
        int v = q[u][i];
        if(vis[v]){
            ans[num[u][i]] = dis[u]+dis[v]-2*dis[f(v)];
        }
    }
}

int main(){
    int t, n, m;
    //ios::sync_with_stdio(false);
    scanf("%d", &t);
    while(t --){
      scanf("%d%d", &n, &m);
      for(int i = 1; i <= n; ++ i){
        map[i].clear(); q[i].clear();
        fat[i] = i; vis[i] = 0;
      }
      int a, b, c;
      for(int i = 0; i < n-1; ++i){
        scanf("%d%d%d", &a, &b, &c);
        node temp;
        temp.to = a; temp.val = c;
        map[b].push_back(temp);
        temp.to = b;
        map[a].push_back(temp);
      }
      for(int i = 0; i < m; ++i){
        scanf("%d%d", &a, &b);
        q[a].push_back(b);
        q[b].push_back(a);
        num[a].push_back(i);
        num[b].push_back(i);
      }
      //memset(vis, 0, sizeof(vis));
      Lca(1, 0);
      for(int i = 0; i < m; ++ i) printf("%d\n", ans[i]);
    }
    return 0;
}
时间: 2024-12-28 09:20:44

Hdoj 2586 How far away ? 【LCA】的相关文章

hdoj 2586 How far away ? 【Tarjan离线LCA】

题目:hdoj 2586 How far away ? 题意:给出一个有权树,求任意两点的之间的距离. 分析:思想就是以一个点 root 作为跟变成有根数,然后深搜处理处所有点到跟的距离.求要求的两个点的LCA(最近公共祖先), 然后ans = dis[x] + dis[y] - 2 * dis[LCA(x,y)],可以画图分析一下就知道. 求LCA我用的是Tarjan离线lca,由于询问次数很多,所以这个比较快. AC代码: #include <iostream> #include <

HDU--2586--How far away ?【LCA】

链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 题意:一棵有边权的树,问任意两点间的长度是多少. 思路:做LCA题目看到的这道题,就用LCA做了,其实只用LCA的递归部分就能做这道题了. 用一个数组dis记录根节点到每个节点的距离,则任意两节点a.b间的距离就是dis[a]+dis[b]-2*dis[lca(a,b)]. 我用vector,交G++要RE,交C++得手动扩栈才能过 LCA离线算法 #pragma comment(linker,

hdu 2586 How far away ?倍增LCA

hdu 2586 How far away ?倍增LCA 题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=2586 思路: 针对询问次数多的时候,采取倍增求取LCA,同时跟新距离数组 因为 \(2^{16} > 40000\) 所以所以表示祖先的数组dp[][]第二维取到16即可 就这道题来说,与比较tarjan比较,稍快一点 代码: #include <iostream> #include <algorithm> #includ

hdoj Last non-zero Digit in N! 【数论】

找规律! 求N!最后非0位的值.比如2是120的最后一个不是0的值. 输入N比较大,要大数保存. 注意到最后0的个数是与5的因数的个数相等.设f(n)为n!的最后非0位. 那么f(n)=((n%5)!* f(n/5) *2^(n/5))%10 因数2的个数始终大于5,从1开始每连续5个划分为1组,其中5的倍数只提取出一个因数5后, 组成一个新的数列1到n/5,我们有1*2*3*4*5=6*7*8*9*5=2(取最后一个非0位),这里就是2^(n/5). 再乘上剩下来的几个数字即可 (比如n是12

Hdoj 2200 Eddy&#39;s AC难题 【数学】

Eddy's AC难题 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4198 Accepted Submission(s): 1967 Problem Description Eddy是个ACMer,他不仅喜欢做ACM题,而且对于Ranklist中每个人的ac数量也有一定的研究,他在无聊时经常在纸上把Ranklist上每个人的ac题目的数

怎么使用启动U盘给电脑装系统呢?——————【Badboy】

[以下经验] 怎么使用启动U盘给电脑ghost系统呢?安装ghost系统的步骤方法复杂吗?有些不懂安装系统的朋友会认为安装ghost系统非常复杂,一直都学不好.下面就看看小编为大家分享的ghost系统操作方法吧! 方法/步骤 第一步:准备启动U盘. 第二步:然后下载一个镜像文件,将ghost文件copy到U盘GHO目录,把文件名修改成"auto.gho".然后拔出U盘,重启电脑. 第三步:然后进入到WINPE功能选择界面,选择运行U大师微型PE(适用老机). 第四步:进入到winpe启

jQuery如何停止元素的animate动画,还有怎样判断是否处于动画状态?【转】

停止元素的动画方法:stop() 语法结构:stop([clearQueue],[gotoEnd]) clearQueue 和 gotoEnd 都为可选参数,为布尔值. clearQueue : 是否要清空未执行玩的动画列表 gotoEnd : 是否直接将正在执行的动画跳转到末状态 经常在hover时间的动画效果里用到 stop() 方法,可以避免动画效果与光标动作不一致时导致的延迟动画. 例如: $(".test").hover(function(){     $(this).sto

为什么我们买的U盘或内存卡大小都比上面标注的大小小?——【Badboy】

说到这个大小问题,很多人都觉得自己被坑了?嘿嘿,那我们先从计算机里的大小单位说起了,计算机中最小的储存单位是比特,如果不深究的话,是比特,1TB=1024GB 1GB=1024MB 1MB=1024KB 1KB=1024BIT,这是计算机最基本的单位(还有更大的,详情请登录www.baidu.com 查找咨询    本人ID 1977870896AA),但是生产厂商为了比较方便运算等工作,把1TB=1000GB ....  , 所以做一些存储设备的厂商比如做了一个8G U盘,当制作完成在电脑上运

向“生物力学之父”冯元桢先生学习什么?【转载】

[转载] 原帖:http://blog.sciencenet.cn/blog-485553-753738.html 在企业从事技术工作的我本该与“生物力学之父”冯元桢先生没什么交集,但因本人从事机械行业的流体传动与控制技术领域,幻想能否用流体力学与机械结构作类比,解析高血压现象,于是找来一本<人体解剖学>的书籍来看(仅看了血液循环一章),发现血液循环系统和流体传动系统原理是一样的,心脏.瓣膜.血管.血液完全可用泵.阀.管道.矿物油作类比.流体传动系统要服从流体力学,机构学,热力学规律,血液循环