hdu2586How far away ?

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

Total Submission(s): 6456    Accepted Submission(s): 2432

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

#include<map>
#include<string>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<queue>
#include<vector>
#include<iostream>
#include<algorithm>
#include<bitset>
#include<climits>
#include<list>
#include<iomanip>
#include<stack>
#include<set>
using namespace std;
int head[40000+10],tail;
struct Edge
{
    int val,to,next;
}edge[2*40000+10];
void add(int from,int to,int val)
{
    edge[tail].val=val;
    edge[tail].to=to;
    edge[tail].next=head[from];
    head[from]=tail++;
}
int step,fst[40000+10],dth[40000*2+10],dis[40000+10],point[40000*2+10];
bool vis[40000+10];
void dfs(int from,int dep)
{
    vis[from]=1;
    fst[from]=++step;
    dth[step]=dep;
    point[step]=from;
    for(int i=head[from];i!=-1;i=edge[i].next)
    {
        int to=edge[i].to,val=edge[i].val;
        if(!vis[to])
        {
            dis[to]=dis[from]+val;
            dfs(to,dep+1);
            point[++step]=from;
            dth[step]=dep;
        }
    }
}
int dp[40000*2+10][20];
void create(int n)
{
    n*=2;
    for(int i=0;i<n;i++)
        dp[i][0]=i;
    for(int j=1;(1<<j)<n;j++)
        for(int i=0;i+(1<<j)-1<n;i++)
        {
            int one=dp[i][j-1],two=dp[i+(1<<j-1)][j-1];
            dp[i][j]=dth[one]<dth[two]?one:two;
        }
}
int seek(int l,int r)
{
    int k,len;
    for(k=0,len=r-l+1;(1<<k+1)<=len;k++);
	int one=dp[l][k],two=dp[r-(1<<k)+1][k];
    return dth[one]<dth[two]?point[one]:point[two];
}
int cnt(int l,int r)
{
    int one=fst[l],two=fst[r];
    if(one>two)
        swap(one,two);
    return dis[l]+dis[r]-2*dis[seek(one,two)];
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n,m;
        scanf("%d%d",&n,&m);
        tail=0;
        memset(head,-1,sizeof(head));
        for(int i=1;i<n;i++)
        {
            int from,to,val;
            scanf("%d%d%d",&from,&to,&val);
            add(from,to,val);
            add(to,from,val);
        }
        dis[1]=0;
        memset(vis,0,sizeof(vis));
        step=-1;
        dfs(1,0);
        create(n);
        while(m--)
        {
            int l,r;
            scanf("%d%d",&l,&r);
            printf("%d\n",cnt(l,r));
        }
    }
}
时间: 2024-10-10 08:46:31

hdu2586How far away ?的相关文章

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,

并查集总结篇

1.模板题poj1611the suspects 每个组内的人,同一个组内都是感染者,问与"0"号人有关的有多少人 #include <iostream> #include<cstdio> using namespace std; const int MAXN = 1000100; struct DS { int f[MAXN]; void init(int n) { for(int i=0;i<n;i++) f[i]=i; } int ff(int x)

三支一扶成绩什么时候出来?

三支一扶考试成绩是各位考生在参加了三支一扶考试之后关注的第一件事,那么在三支一扶考试之后到底三支一扶成绩什么时候出来[gwy.kaoshib.com/szyf/cjcx/52863.html]呢?今天小编就为大家介绍一下. 三支一扶成绩什么时候出来这个问题使参加完考试之后的一个重大问题,三支一扶成绩一般会在考试进行的半个月之后进行考试成绩的发布,但是也有一些省份会在考试结束之后的第二天发布此次的考试成绩. 因为三支一扶考试不是统一进行考试,考试时间不一样,当然三支一扶成绩什么时候出来的时间也就不

苹果三星新“机皇”遇冷,国产手机该高兴吗?

几年前这还是让人不敢想象的情景:安卓与iOs两大阵营的"机皇"---Note8和iPhoneX,在中国"手机春晚"的年度压轴表演,就真的仅仅是"表演"而已.整个中国手机产业界完全是冷眼旁观.这旁观不是羡慕和嫉妒,而是真的有点漠不关心. 原因简单明了:Note8与iPhoneX刚一发布就已经被所有人认定,在中国市场没有前途.而主流消费者几乎可以肯定地说,将会在一阵感慨之后立刻转身投入国产手机的怀抱. 手机市场的竞争,无非 硬件性价比 + 软件生态

三百六十度全景图如何拍摄?

三百六十度全景图如何拍摄?随着全景技术的发展,全景拍摄也成为了一种十分新潮的摄影方式.全景摄影也有很多学问,而且随着全景照片的用途越来越多,拍摄全景的设备也越来越多.今天我们就介绍几种十分另类的360全景图拍摄方法,这些酷雷曼360全景图拍摄方法让你大开眼界. 工具/原料 相机 鱼眼镜头 云台 三角支架 方法/步骤 1 吊锤辅助360全景图拍摄方法 吊线保证拍摄时相机以节点旋转,使用吊线进行全景拍摄线不要太长,50CM以内比较容易控制,有时也到一米多在胸口位置进行拍摄,重锤容易晃动,很难对准.吊

张书乐:BATJ联姻银行:智慧银行会来的更猛烈些吗?

几乎一夜之间,一直有些势成水火的主流互联网金融平台,都分别和四大国有银行牵上了手. 2017年3月28日,阿里巴巴集团.蚂蚁金服集团和中国建设银行签署了三方战略合作协议:6月16日,工商银行牵手京东刘强东进行全面合作,6月20日,百度与农业银行宣布达成战略合作:6月22日,腾讯则下了个"双黄蛋",同一天与中国银行和华夏银行均签战略合作协议-- 至此,互联网(不限于金融)领域俗称的BATJ(百度.阿里.腾讯.京东)与四大国有银行工.农.中.建,均结成了互助对子. 科技金融还是金融科技,这

如何上传代码到github?

如何上传代码到github? 首先你需要一个github账号,所有还没有的话先去注册吧! https://github.com/ 我们使用git需要先安装git工具,这里给出下载地址,下载后一路直接安装即可: https://git-for-windows.github.io/ 1.进入Github首页,点击New repository新建一个项目  2.填写相应信息后点击create即可 Repository name: 仓库名称 Description(可选): 仓库描述介绍 Public,

张书乐:无人便利店 有风无浪新蓝海,怎么闯?

进店扫码获得电子入场码,选好货物后自动结算,节约下排队和结账的时间,快速离开没有一个售货员的便利店.这样颇有点小科幻的场景,在当下中国已经出现. "F5未来商店"对外宣称,获创新工场3000万元A+轮投资:国内首个商用可规模化复制的24小时无人便利店"缤果盒子"宣布完成A轮系列融资,融资额超过1亿元:阿里首家无人超市"淘咖啡"也在7月第二届淘宝造物节上与首次亮相. 又一个互联网+的大风口来临了吗?有可能成为颠覆实体零售的新势力吗?或许答案是,想得

产品规划:如何规划代金券系统?

ps:此代金券系统的规划是建立在SDK的产品上 一.代金券需求 近期,公司的游戏产品需要做折扣系统,目的提高付费率.简单来说就是玩家购买游戏商品获得一定的折扣. 二.关于折扣形式 这里折扣形式可以有: 直接在产品进行打折: 发放活动券: 提供充值返利: 代币等. 1.直接在产品进行折扣处理 这种方法最为简单,无论是技术实现还是产品角度都是最方便的,但是用户体验感也是最不好的.用户很直观看到有打折,打折仅仅打折并没有拿到实际的东西,用户得不到真实的感知质量,这就是用户感知性: 2.发放活动券形式