HDU 2586 How far away ?【LCA】
任意门:http://acm.hdu.edu.cn/showproblem.php?pid=2586
How far away ?
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 24439 Accepted Submission(s): 9739
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.
3 2
1 2 10
3 1 15
1 2
2 3
2 2
1 2 100
1 2
2 1
25
100
100
题意概括:
给一颗 N 个结点,N-1条边的树,和 M 次查询(离线)
解题思路:
要查询两点到最近公共祖先的距离和,首先要预处理出根结点到各个结点的距离(DFS)
然后 Tarjan 找出最近的公共祖先,两个结点到根结点的距离之和减去两倍的最近公共祖先到根结点的距离就是该查询的答案了。
AC code:
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#define INF 0x3f3f3f3f
#define LL long long
const int MAX_N = 4e4+;
using namespace std; struct Edge{int v, nxt, w;}edge[MAX_N<<]; //静态邻接表
struct Query
{
int v, id;
Query(){};
Query(int _v, int _id):v(_v), id(_id){};
}; vector<Query> q[MAX_N]; // !!! //查询关系动态二维矩阵 int head[MAX_N], cnt; //静态邻接表头节点,边数
int dis[MAX_N]; //各结点到根结点的距离
int fa[MAX_N]; //并查集 祖先数组
bool vis[MAX_N], in[MAX_N]; //深搜用,找根结点用
int ans[MAX_N]; // !!! //各查询答案
int N, M; //结点数,查询数 void init()
{
memset(head, -, sizeof(head)); //初始化
memset(vis, false, sizeof(vis));
memset(in, false, sizeof(in));
memset(dis, , sizeof(dis));
memset(ans, , sizeof(ans));
cnt = ;
} void AddEdge(int from, int to, int weight) //静态邻接表加边操作
{
edge[cnt].v = to;
edge[cnt].w = weight;
edge[cnt].nxt = head[from];
head[from] = cnt++;
} int getfa(int x) //找祖先
{
int root = x;
while(fa[root] != root) root = fa[root]; int tmp;
while(fa[x] != root){
tmp = fa[x];
fa[x] = root;
x = tmp;
}
return root;
} void dfs(int s) //预处理各根结点到祖先的距离
{
int rt = s;
for(int i = head[s]; i != -; i = edge[i].nxt){
dis[edge[i].v] = dis[rt] + edge[i].w;
dfs(edge[i].v);
}
} void Tarjan(int s) // LCA
{
int root = s;
fa[s] = s;
for(int i = head[s]; i != -; i = edge[i].nxt){
int Eiv = edge[i].v;
Tarjan(Eiv);
fa[getfa(Eiv)] = s;
}
vis[s] = true;
for(int i = ; i < q[s].size(); i++){
if(vis[q[s][i].v] && !ans[q[s][i].id]){
ans[q[s][i].id] = dis[q[s][i].v] + dis[s] - *dis[getfa(q[s][i].v)];
}
}
} int main()
{
int T_case;
scanf("%d", &T_case);
while(T_case--){
init();
scanf("%d %d", &N, &M);
for(int i = , u, v, w; i < N; i++){ //建树
scanf("%d %d %d", &u, &v, &w);
AddEdge(u, v, w);
in[v] = true;
} for(int i = , u, v; i <= M; i++){ //储存查询信息(离线)
scanf("%d %d", &u, &v);
q[u].push_back(Query(v, i));
q[v].push_back(Query(u, i));
} int root = ;
for(int i = ; i <= N; i++) if(!in[i]){root = i; break;} //找树根结点 dfs(root); //预处理
Tarjan(root); //LCA for(int i = ; i <= M; i++){
printf("%d\n", ans[i]);
}
//puts("");
}
return ;
}
HDU 2586 How far away ?【LCA】的更多相关文章
- HDU 2586 How far away ?【LCA模板题】
传送门:http://acm.hdu.edu.cn/showproblem.php?pid=2586 题意:给你N个点,M次询问.1~N-1行输入点与点之间的权值,之后M行输入两个点(a,b)之间的最 ...
- HDU 2586——How far away ?——————【LCA模板题】
How far away ? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
- hdu 2586 How far away ?倍增LCA
hdu 2586 How far away ?倍增LCA 题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=2586 思路: 针对询问次数多的时候,采取倍增 ...
- HDU - 2586 How far away ?(LCA模板题)
HDU - 2586 How far away ? Time Limit: 1000MS Memory Limit: 32768KB 64bit IO Format: %I64d & ...
- HDU 2586.How far away ?-离线LCA(Tarjan)
2586.How far away ? 这个题以前写过在线LCA(ST)的,HDU2586.How far away ?-在线LCA(ST) 现在贴一个离线Tarjan版的 代码: //A-HDU25 ...
- HDU 2586 How far away ?(LCA在线算法实现)
http://acm.hdu.edu.cn/showproblem.php?pid=2586 题意:给出一棵树,求出树上任意两点之间的距离. 思路: 这道题可以利用LCA来做,记录好每个点距离根结点的 ...
- HDU 2586 How far away ?(LCA模板 近期公共祖先啊)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586 Problem Description There are n houses in the vi ...
- HDU 2586.How far away ?-在线LCA(ST)-代码很认真的写了注释(捞到变形)
2018.9.10 0:40 重新敲一遍,然后很认真的写了注释,方便自己和队友看,刚过去的一天的下午打网络赛有一题用到了这个,但是没写注释,队友改板子有点伤,因为我没注释... 以后写博客,代码要写注 ...
- HDU 2586 How far away ? 离线lca模板题
How far away ? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)To ...
随机推荐
- Map接口常用实现类学习
HashMap 1.6的HashMap:数组加单向链表结构 最重要的内部类Entry,全类名是java.util.HashMap.Entry,是个静态类,实现了Map.Entry接口.HashMap. ...
- python查看模块版本及所在文件夹
# 以Numpy为例 第一种方法:import numpy as np np.__version__ >>> '1.12.1' np.__file__ >>> '/ ...
- 1、java线程模型
要了解多线程,先需要把java线程模型搞清楚,否则有时候很难理清楚一个问题. 硬件多线程: 物理机硬件的并发问题跟jvm中的情况有不少相似之处,物理机的并发处理方案对于虚拟机也有相当大的参考意义.在买 ...
- docker~环境变量到底怎么用
docker已经用了两年多了,从开始的简单应用到现在的自动化部署,已经越来越感觉到它的威力,今天把Hitchhiker部署完成后,看到了它与.net core项目有个类似的地方,就是对于多环境部署的时 ...
- Unity3D 发布成PC端常用设置
本文,基于Unity 5.6pro版本来发布PC端.文中若有不妥之处,欢迎各位指出! 一.如何去掉Unity官方水印? 首先,你需要pro版本的Unity3D.如果,你是personal版本的话,就需 ...
- 九度oj题目1012:畅通工程
题目1012:畅通工程 时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:6643 解决:2863 题目描述: 某省调查城镇交通状况,得到现有城镇道路统计表,表中列出了每条道路直接连通的城镇. ...
- C++程序设计基础(8)main函数
注:读<程序员面试笔记>笔记总结 1.知识点 (2)main函数的形式 //first type int main() //second type int main(int argc,ch ...
- bzoj 2741: 【FOTILE模拟赛】L
Description FOTILE得到了一个长为N的序列A,为了拯救地球,他希望知道某些区间内的最大的连续XOR和. 即对于一个询问,你需要求出max(Ai xor Ai+1 xor Ai+2 .. ...
- Quartz使用及注意事项
Quartz使用及注意事项 前提:目前由于公司业务决定,大量使用Quartz,每天固定的时间点执行相应的业务逻辑,,几十个时间点应该是有的,某一个时间点如果没有执行带来的问题是巨大的.Quartz的稳 ...
- mysql忘记root密码的解决方法
Windows下mysql忘记root密码的解决方法 1. 首先检查mysql服务是否启动,若已启动则先将其停止服务,可在开始菜单的运行,使用命令:net stop mysql 或者在windows任 ...