[poj1986]Distance Queries(LCA)
解题关键:LCA模板题
复杂度:$O(n\log n)$
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
#include<iostream>
typedef long long ll;
using namespace std;
const int maxn=;
const int maxm=;
int _pow[maxm],m,n;
int head[maxn],tot;
int ver[maxn*],depth[maxn*],first[maxn],rmq[maxn*][maxm],id;//5个数组,注意哪个需要乘2
ll dis[maxn];
inline int read(){
char k=;char ls;ls=getchar();for(;ls<''||ls>'';k=ls,ls=getchar());
int x=;for(;ls>=''&&ls<='';ls=getchar())x=(x<<)+(x<<)+ls-'';
if(k=='-')x=-x;return x;
} struct edge{
int to,w,nxt;
}e[maxn*];//链式前向星建树 void init(){
memset(head,-,sizeof head);
tot=;
id=;
} void add_edge(int u,int v,int w){
e[tot].to=v;
e[tot].w=w;
e[tot].nxt=head[u];
head[u]=tot++;
} void dfs(int u,int fa,int dep){
ver[++id]=u;//第i个访问到的结点编号
depth[id]=dep;//第i个访问到的结点深度
first[u]=id;
for(int i=head[u];i!=-;i=e[i].nxt){
int v=e[i].to;
int w=e[i].w;
if(v==fa) continue;
dis[v]=dis[u]+w;//dis是先序遍历求
dfs(v,u,dep+);
ver[++id]=u;//后序遍历,再次访问父节点
depth[id]=dep;
}
} void rmq_init(int n){
int k=int(log(n)/log());
for(int i=;i<=n;++i) rmq[i][]=i;
for(int j=;j<=k;++j){
for(int i=;i+_pow[j]-<=n;++i){//因为存的是索引
int a=rmq[i][j-],b=rmq[i+_pow[j-]][j-];
if(depth[a]<depth[b]) rmq[i][j]=a;
else rmq[i][j]=b;
}
}
} int rmq_query(int l,int r){
int k=int(log(r-l+1.0)/log(2.0));
int a=rmq[l][k],b=rmq[r-_pow[k]+][k];
if(depth[a]<depth[b]) return a;
else return b;
}//返回的依然是索引 int LCA(int u,int v){
int x=first[u],y=first[v];
if(x>y)swap(x,y);
int res=rmq_query(x,y);
return ver[res];
} int main(){
for(int i=;i<maxm;++i) _pow[i]=<<i; //预处理2^n
int t,a,b,c;
init();
n=read(),m=read();
for(int i=;i<m;++i){
scanf("%d%d%d %*c",&a,&b,&c);
add_edge(a,b,c);
add_edge(b,a,c);
}
dfs(,-,);
rmq_init(*n-);
int m;
m=read();
for(int i=;i<m;++i){
a=read();b=read();
int ans=LCA(a,b);
printf("%lld\n",dis[a]+dis[b]-*dis[ans]);
} return ;
}
[poj1986]Distance Queries(LCA)的更多相关文章
- poj-1986 Distance Queries(lca+ST+dfs)
题目链接: Distance Queries Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 11531 Accepted ...
- POJ.1986 Distance Queries ( LCA 倍增 )
POJ.1986 Distance Queries ( LCA 倍增 ) 题意分析 给出一个N个点,M条边的信息(u,v,w),表示树上u-v有一条边,边权为w,接下来有k个询问,每个询问为(a,b) ...
- POJ1986 Distance Queries (LCA)(倍增)
Distance Queries Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 12950 Accepted: 4577 ...
- poj 1986 Distance Queries LCA
题目链接:http://poj.org/problem?id=1986 Farmer John's cows refused to run in his marathon since he chose ...
- POJ 1986 Distance Queries(LCA Tarjan法)
Distance Queries [题目链接]Distance Queries [题目类型]LCA Tarjan法 &题意: 输入n和m,表示n个点m条边,下面m行是边的信息,两端点和权,后面 ...
- POJ 1986 - Distance Queries - [LCA模板题][Tarjan-LCA算法]
题目链接:http://poj.org/problem?id=1986 Description Farmer John's cows refused to run in his marathon si ...
- POJ 1986 Distance Queries LCA两点距离树
标题来源:POJ 1986 Distance Queries 意甲冠军:给你一棵树 q第二次查询 每次你问两个点之间的距离 思路:对于2点 u v dis(u,v) = dis(root,u) + d ...
- poj1986 Distance Queries(lca又是一道模版题)
题目链接:http://poj.org/problem?id=1986 题意:就是老问题求val[u]+val[v]-2*val[root]就行.还有这题没有给出不联通怎么输出那么题目给出的数据一定 ...
- POJ 1986 Distance Queries(Tarjan离线法求LCA)
Distance Queries Time Limit: 2000MS Memory Limit: 30000K Total Submissions: 12846 Accepted: 4552 ...
随机推荐
- wpf自定义colorpicker
自定义colorpicker <ObjectDataProvider MethodName="GetType" ObjectType="{x:Type system ...
- ViewPager总结
https://github.com/youth5201314/banner compile 'com.youth.banner:banner:1.4.9' private void setBanne ...
- _THROW 何解?
在看/usr/include/........中.h头文件对函数接口的定义时,总是能看到在函数结尾加一个_THROW,一时不明白这是什么意思,而且对于有些POSIX和ISO C不承认或未明确的定义的函 ...
- android菜鸟学习笔记12----Android控件(一) 几个常用的简单控件
主要参考<第一行代码> 1.TextView: 功能与传统的桌面应用开发中的Label控件相似,用于显示文本信息 如: <TextView android:layout_width= ...
- [Python]Pip换源以及设置代理
Install python package with proxy sudo pip install python-magic --proxy=https://your-proxy.com 2.No ...
- 3行代码 多元线性方程组 rank=4 多元-一元 降元
对于线性方程组Ax=b 对A和b执行同样的一串行初等运算, 那么该方程组的解集不发生变化. [未知-已知 高阶--低阶] http://mathworld.wolfram.com/CramersR ...
- 题解 P1095 【守望者的逃离】
贪心.数组都不用开那种. 考虑跑步距离的构成.发现跑步只有三种情况构成 休息 传送 朴素地跑 显然,如果可以传送,我们就不要朴素地跑步.因为\(17\le 60 \div 2 =30\). 假如我们知 ...
- 流畅的python学习笔记:第十三章:重载运算符__add__,__iadd__,__radd__,__mul__,__rmul__,__neg__,__eq__,__invert__,__pos__
在前面第十章以及第一章的时候介绍了Vector对象的运算符重载.第十三章专门介绍运算符重载.这里我们看几个之前没讲过的运算符__neg__,__pos__,__invert__ class Vecto ...
- Java for LeetCode 094 Binary Tree Inorder Traversal
解题思路: 中序遍历,左子树-根节点-右子树 JAVA实现如下: public List<Integer> inorderTraversal(TreeNode root) { List&l ...
- GDB调试core文件(2)
使用gdb和core dump迅速定位段错误 关键字:gdb.段错误.core dump 一.什么是core dump core:内存.核心的意思: dump:抛出,扔出: core dump:前提: ...