距离B - Distance in the Tree

还是普通的LCA但是要求的是两个节点之间的距离,学到了一些

一开始我想用带权并查集进行优化,但是LCA合并的过程晚于离线计算的过程,所以路径长度会有所偏差

所以失败告终

网上查询之后懂得要提前进行一下预处理,在输入完全部的边之后,也就是数形成之后,计算dis——》也就是每个点到树根的长度

之后进行询问查询时:u,v 和 rt 这样uv的距离就是dis[u] + dis[v] - 2 * dis[rt]很好理解

时间复杂度也还可以

#include <iostream>
#include <cstdio>
#include <string.h>
using namespace std;
const int maxn = 5e4 + 50;
const int maxm = 7e4 + 6e3;
int id[maxn],qid[maxn];
int cnt,qcnt;
int pre[maxn],cost[maxn];
int vis[maxn];
struct node{
int to,pre,cost;
}e[maxn * 2];
struct node2{
int to,ads,pre;
}q[maxm * 2];
int ans[maxm];
int Find(int x)
{
//cout<<x<<endl;
if(pre[x] == x)return x;
else
{
//cost[x] += cost[pre[x]];
return pre[x] = Find(pre[x]);
}
} void join(int a,int b)
{
int fa = Find(a),fb = Find(b);
if(fa != fb)
{
pre[fb] = fa;
}
} void init(int n)
{
for(int i = 0;i <= n;i++)
{
pre[i] = i;
vis[i] = 0;
cost[i] = 0;
}
memset(id,-1,sizeof(id));
memset(qid,-1,sizeof(qid));
cnt = qcnt = 0;
} void add(int from,int to,int cost)
{
e[cnt].to = to;
e[cnt].pre = id[from];
e[cnt].cost = cost;
id[from] = cnt++;
}
void qadd(int from,int to,int i)
{
q[qcnt].to = to;
q[qcnt].ads = i;
q[qcnt].pre = qid[from];
qid[from] = qcnt++;
}
void get_cost(int rt,int dis)
{
vis[rt] = 1;
cost[rt] = dis;
for(int i = id[rt];~i;i = e[i].pre)
{
int to = e[i].to;
int cos = e[i].cost;
if(!vis[to])
{
get_cost(to,dis+cos);
}
}
}
void tarjan(int rt)
{
//cout<<rt<<endl;
vis[rt] = -1;
for(int i = id[rt];~i;i = e[i].pre)
{
int to = e[i].to;
int cos = e[i].cost;
if(!vis[to])
{
tarjan(to);
join(rt,to);
}
//cout<<"cs"<<to<<" "<<cost[to]<<endl;
} vis[rt] = 1;
for(int i = qid[rt];~i;i = q[i].pre)
{
int to = q[i].to;
if(vis[to] == 1)
{
//cout<<"to : "<<to<<endl;
//cout<<"pre[to]: "<<pre[to]<<endl;
//cout<<rt<<" "<<to<<"cost: "<<cost[rt]<<" "<<cost[to]<<endl;
int lca = Find(to);
ans[q[i].ads] = abs(cost[lca] - cost[rt]) + abs(cost[lca] - cost[to]);
}
}
}
int main()
{
int n,m,u,v,w;
scanf("%d",&n);
init(n);
for(int i = 1;i < n;++i)
{
scanf("%d%d%d",&u,&v,&w);
add(u,v,w);
add(v,u,w);
}
get_cost(0,0);
memset(vis,0,sizeof(vis));
scanf("%d",&m);
for(int i = 1;i <= m;++i)
{
scanf("%d%d",&u,&v);
qadd(u,v,i);
qadd(v,u,i);
}
tarjan(0);
for(int i = 1;i <= m;++i)
{
printf("%d\n",ans[i]);
}
return 0;
}
/*
7
0 1 1
0 2 1
0 3 1
1 4 1
2 5 1
2 6 1
40
0 1
0 2
0 3
0 4
0 5
0 6
0 0
1 1
1 2
1 3
1 4
1 5
1 6
1 0
2 0
2 1
2 2
2 3
2 4
2 5
2 6
3 0
3 1
3 2
3 3
3 4
3 5
3 6
4 0
4 1
4 2
4 3
4 4
4 5
4 6
5 0
5 1
5 2
5 3
5 4
*/

距离LCA离线算法Tarjan + dfs + 并查集的更多相关文章

  1. LCA离线算法Tarjan详解

    离线算法也就是需要先把所有查询给保存下来,最后一次输出结果. 离线算法是基于并查集实现的,首先就是初始化P[i] = i. 接下来对于每个点进行dfs: ①首先判断是否有与该点有关的查询,如果当前该点 ...

  2. LCA离线算法Tarjan的模板

    hdu 2586:题意:输入n个点的n-1条边的树,m组询问任意点 a b之间的最短距离 思路:LCA中的Tarjan算法,RMQ还不会.. #include <stdio.h> #inc ...

  3. HDU 2874 LCA离线算法 tarjan算法

    给出N个点,M条边.Q次询问 Q次询问每两点之间的最短距离 典型LCA 问题   Marjan算法解 #include "stdio.h" #include "strin ...

  4. POJ1986 DistanceQueries 最近公共祖先LCA 离线算法Tarjan

    这道题与之前那两道模板题不同的是,路径有了权值,而且边是双向的,root已经给出来了,就是1,(这个地方如果还按之前那样来计算入度是会出错的.数据里会出现多个root...数据地址可以在poj的dis ...

  5. Tarjan的LCA离线算法

    LCA(Least Common Ancestors)是指树结构中两个结点的最低的公共祖先.而LCA算法则是用于求两个结点的LCA.当只需要求一对结点的LCA时,我们很容易可以利用递归算法在O(n)的 ...

  6. Leetcode题目200.岛屿数量(BFS+DFS+并查集-中等)

    题目描述: 给定一个由 '1'(陆地)和 '0'(水)组成的的二维网格,计算岛屿的数量.一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的.你可以假设网格的四个边均被水包围. 示例 ...

  7. LCA(最近公共祖先)离线算法Tarjan+并查集

    本文来自:http://www.cnblogs.com/Findxiaoxun/p/3428516.html 写得很好,一看就懂了. 在这里就复制了一份. LCA问题: 给出一棵有根树T,对于任意两个 ...

  8. LCA 离线的Tarjan算法 poj1330 hdu2586

    LCA问题有好几种做法,用到(tarjan)图拉算法的就有3种.具体可以看邝斌的博客.http://www.cnblogs.com/kuangbin/category/415390.html 几天的学 ...

  9. POJ 1470 Closest Common Ancestors (最近公共祖先LCA 的离线算法Tarjan)

    Tarjan算法的详细介绍,请戳: http://www.cnblogs.com/chenxiwenruo/p/3529533.html #include <iostream> #incl ...

随机推荐

  1. (轉)EasyUI - DataGrid 去右边空白滚动条列

    熟悉 EasyUI - DataGrid 的童鞋应该会注意到这样一个情景: 想去掉这块,找了下资料,发现也有人同样纠结:http://www.cnblogs.com/hantianwei/p/3440 ...

  2. HDU_2112(最短路)

    经过锦囊相助,海东集团终于度过了危机,从此,HDU的发展就一直顺风顺水,到了2050年,集团已经相当规模了,据说进入了钱江肉丝经济开发区500强.这时候,XHD夫妇也退居了二线,并在风景秀美的诸暨市浬 ...

  3. 如何搭建http服务仓库

    1.拷贝仓库repo-A文件到服务器/media/D: 2.通过createrepo_c 生成仓库rpm信息数据 cd repo-A createrepo . 3.chmod -R 775  repo ...

  4. MFC窗口颜色的设置

    本文主要介绍对话框背景色以及控件颜色的设置(SetDialogBkColor()不再被支持). 对话框背景色的设置 1.重载OnPaint()函数,即WM_PAINT消息,代码如下所示: void C ...

  5. Ubuntu 双网卡设置

    闲话不多说,直接正题 因为chinanet信号不强,所以买了个usb无线网卡,平常又要做开发,要连着开发板,不知怎么回事,一旦自带无线网卡连上内网的无线路由,就不能访问外网了. 网上搜了好久,终于查到 ...

  6. How to ignore files and directories in subversion?

    Step 1 Copy the files and directories to other place. Step 2 Delete the files and directories. Step ...

  7. js处理img标签加载图片失败,显示默认图片

    1.第一种方法: 如果已经引入了jquery插件,就很好办.没有的话,如果实在需要,可以附上代码: script(type='text/javascript', src="http://aj ...

  8. openssl初步使用

    centos平台 md5.c #include <stdio.h> #include <string.h> #include <stdlib.h> //#inclu ...

  9. 视频基础知识:浅谈视频会议中H.264编码标准的技术发展

    浅谈视频会议中H.264编码标准的技术发展 浅谈视频会议中H.264编码标准的技术发展 数字视频技术广泛应用于通信.计算机.广播电视等领域,带来了会议电视.可视电话及数字电视.媒体存储等一系列应用,促 ...

  10. 字符串方法 split() & replace()

    split() 语法:stringObject.split(separator) 功能:把一个字符串分割成字符串数组 返回值:Array 说明:separator 是必须的,分隔符. var str= ...