2018.9.10 0:40 重新敲一遍,然后很认真的写了注释,方便自己和队友看,刚过去的一天的下午打网络赛有一题用到了这个,但是没写注释,队友改板子有点伤,因为我没注释。。。

以后写博客,代码要写注释,要把题目意思写上。。。

我好捞啊。。。

How far away ?

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 21408    Accepted Submission(s): 8432

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模板题
 
 
代码:
 //HDU2586
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<bitset>
#include<cassert>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<deque>
#include<iomanip>
#include<list>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
using namespace std;
typedef long long ll; const double PI=acos(-1.0);
const double eps=1e-;
const ll mod=1e9+;
const int inf=0x3f3f3f3f;
const int maxn=4e4+;
const int maxm=+;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); int dp[maxn<<][];//数组记得开2倍,因为遍历之后序列长度变为2*n-1
bool vis[maxn];//标记 struct node{
int u,v,w,next;
}edge[maxn<<]; int tot,head[maxn];//head保存的是以当前节点为起点的所有边中最后一条边的编号 int num; inline void add(int u,int v,int w)
{
edge[num].u=u;edge[num].v=v;edge[num].w=w;//存边和权值
edge[num].next=head[u];head[u]=num++;//next保存的是以u为起点的上一条边的编号
u=u^v;v=u^v;u=u^v;//节点互换,存两次,因为为无向图,(u,v)存一次,(v,u)存一次,以下操作同上
edge[num].u=u;edge[num].v=v;edge[num].w=w;
edge[num].next=head[u];head[u]=num++;
} int ver[maxn<<],deep[maxn<<],node[maxn<<],dir[maxn<<];
//ver节点编号,dfs搜索过程中的序列,deep深度,node点编号位置,dir距离 void dfs(int u,int dep)
{
vis[u]=true;//标记u节点被访问过
ver[++tot]=u;//存dfs序
node[u]=tot;//节点的dfs序的编号
deep[tot]=dep;//该编号的深度
for(int k=head[u];k!=-;k=edge[k].next)//倒着遍历以u节点为起点的所有边的编号
if(!vis[edge[k].v]){//如果该编号的边未被访问过
int v=edge[k].v,w=edge[k].w;//v表示该边的终点,w表示该边的权值
dir[v]=dir[u]+w;//权值和
dfs(v,dep+);//再往下dfsv节点的深度
ver[++tot]=u;deep[tot]=dep;//表示dfs的时候还要回溯到上面,就是把dfs序保存一下,走到底再返回去去遍历没走过的点
}
}
//可以看以前写的RMQ(ST)的详解https://www.cnblogs.com/ZERO-/p/8456910.html
void ST(int n)//ST操作
{
for(int i=;i<=n;i++)
dp[i][]=i;//初始化为自己
for(int j=;(<<j)<=n;j++){
for(int i=;i+(<<j)-<=n;i++){
int a=dp[i][j-],b=dp[i+(<<(j-))][j-];
dp[i][j]=deep[a]<deep[b]?a:b;
}
}
} int RMQ(int l,int r)
{
int k=;
while((<<(k+))<=r-l+)k++;//最多能跳2的多少次幂
int a=dp[l][k],b=dp[r-(<<k)+][k];//保存的是编号
return deep[a]<deep[b]?a:b;
} int LCA(int u,int v)
{
int x=node[u],y=node[v];
if(x>y)swap(x,y);
int res=RMQ(x,y);
return ver[res];
} int main()
{
int cas;
scanf("%d",&cas);
while(cas--){
int n,q;
num=;
scanf("%d%d",&n,&q);
memset(head,-,sizeof(head));//初始化
memset(vis,false,sizeof(vis));
for(int i=;i<n;i++){
int u,v,w;
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);//存边
}
tot=;dir[]=;
dfs(,);
ST(*n-);
while(q--){
int u,v;
scanf("%d%d",&u,&v);
int lca=LCA(u,v);
printf("%d\n",dir[u]+dir[v]-*dir[lca]);//两点最短距离为每个点到根节点的距离-最近公共祖先到根节点的距离的*2
}
}
return ;
}

就这样,捞咸鱼。。。

༼༎ຶᴗ༎ຶ༽

HDU 2586.How far away ?-在线LCA(ST)-代码很认真的写了注释(捞到变形)的更多相关文章

  1. HDU 2586 How far away ? (LCA)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 LCA模版题. RMQ+LCA: #include <iostream> #incl ...

  2. 【HDU 2586 How far away?】LCA问题 Tarjan算法

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 题意:给出一棵n个节点的无根树,每条边有各自的权值.给出m个查询,对于每条查询返回节点u到v的最 ...

  3. HDU 2586 How far away ? (LCA,Tarjan, spfa)

    题意:给定N个节点一棵树,现在要求询问任意两点之间的简单路径的距离,其实也就是最短路径距离. 析:用LCA问题的Tarjan算法,利用并查集的优越性,产生把所有的点都储存下来,然后把所有的询问也储存下 ...

  4. Hdu 2586 树链剖分求LCA

    Code: #include<cstdio> #include<cstring> #include<vector> #include<algorithm> ...

  5. hdu 2586 How far away?(LCA模板题+离线tarjan算法)

    How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  6. hdu 2586 How far away? (LCA模板)

    题意: N个点,形成一棵树,边有长度. M个询问,每个询问(a,b),询问a和b的距离 思路: 模板题,看代码.DFS预处理算出每个结点离根结点的距离. 注意: qhead[maxn],而不是qhea ...

  7. hdu 2586 How far away ? ( 离线 LCA , tarjan )

    How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  8. HDU 2586.How far away ?-离线LCA(Tarjan)

    2586.How far away ? 这个题以前写过在线LCA(ST)的,HDU2586.How far away ?-在线LCA(ST) 现在贴一个离线Tarjan版的 代码: //A-HDU25 ...

  9. [hdu 2586]lca模板题(在线+离线两种版本)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 在线版本: 在线方法的思路很简单,就是倍增.一遍dfs得到每个节点的父亲,以及每个点的深度.然后 ...

随机推荐

  1. mybatis和redis整合 log4j打印sql语句

    首先,需要在项目中引进jedis-2.8.1.jar包,在pom.xml里加上 <dependency> <groupId>redis.clients</groupId& ...

  2. VSX-5 VSXMusic 编码听音乐

    给VS写个扩展来听音乐的说法,缘来已久,这两天做了个初版,使用豆瓣FM,先发出来. 插件现在只做了VS2013的,别的版本有待下一步支持. 现在暂时只有一个Adornment(就是那个有封面的),一个 ...

  3. Xcode 代码提示功能失效

    前言: 以前好像很少碰到Xcode中代码提示出问题的情况,最近经常遇到这个问题.没有了Xcode的智能提示,发现我已完全不会写代码了. 本来想吐槽下万恶的baidu,鉴于百度前端时间的各种(贴吧.竞价 ...

  4. Mac 小技巧

    本文的大部分技巧来自于池建强老师的<MacTalk.人生元编程>,感谢他的辛苦付出,本文多系整理而已. 终端输入说英语 说英语时我们当然希望有标准发音.在Mac中不需要字典,直接在终端里输 ...

  5. 《Cracking the Coding Interview》——第8章:面向对象设计——题目8

    2014-04-23 23:49 题目:有个棋牌游戏叫Othello,也叫Reversi.请看游戏规则.中文应该叫黑白棋吧,不常玩儿就是了. 解法:既然这题的规则很清楚,也很清楚,我就写了一个命令行的 ...

  6. 程序员必备PC维修法(软件篇)

    学会使用专业软件检测与修复电脑硬件故障问题也是程序员的一种软技能. windows篇 情景:如何获取电脑硬件的真实信息.(如何检验选购回来的硬件是否正品) 自检:使用AIDA64软件检查电脑硬件,能详 ...

  7. ADB push 和ADB pull命令

    adb push命令 :从电脑上传送文件到手机: adb pull命令 :从手机传送文件到电脑上      

  8. PAT——甲级1042:Shuffling Mashine

    终于做到甲级了 就一个感觉....题目是真的看不懂,亏我还是四六级都过了的人....可是看完题愣是一点都不懂是什么意思. 1042 Shuffling Machine (20 point(s)) Sh ...

  9. jquery validate 使用示范

    最近应公司要求做了一个jquery的示例文件,包括:模态窗口怎么实现:jquery validate下的校验:怎么做图片特效:怎么实现异步操作:实现图片上传剪切效果等很多特效: 这里把jquery校验 ...

  10. A Neural Algorithm of Artistic Style

    本系列文章由 @yhl_leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/53931536 1. 资源 Paper: ...