HDU 2586 How far away ? (LCA)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2586
LCA模版题。
RMQ+LCA:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector> using namespace std;
const int MAXN = 4e4 + ;
typedef pair<int , int>P;
vector <P> G[MAXN];
int dep[MAXN] , dis[MAXN] , par[MAXN][] , ok[MAXN]; void init(int n) {
for(int i = ; i <= n ; i++) {
G[i].clear();
ok[i] = ;
}
} void dfs(int root) {
for(int i = ; i < G[root].size() ; i++) {
dis[G[root][i].first] = dis[root] + G[root][i].second;
dfs(G[root][i].first);
}
} void dfs2(int u , int p , int d) {
dep[u] = d;
par[u][] = p;
for(int i = ; i < G[u].size() ; i++) {
dfs2(G[u][i].first , u , d + );
}
} int lca(int u , int v) {
if(dep[u] < dep[v]) {
swap(u , v);
}
for(int k = ; k < ; k++) {
if((dep[u] - dep[v]) >> k & ) {
u = par[u][k];
}
}
if(u == v)
return u;
for(int k = ; k >= ; k--) {
if(par[u][k] != par[v][k]) {
u = par[u][k];
v = par[v][k];
}
}
return par[u][];
} int main()
{
int n , m , q , v , u , d , root , t;
char op[];
scanf("%d" , &t);
while(t--) {
scanf("%d %d" , &n , &m);
init(n);
root = (n + ) * n / ;
for(int i = ; i < n - ; i++) {
scanf("%d %d %d" , &u , &v , &d);
G[u].push_back(P(v , d));
if(!ok[v]) {
root -= v;
ok[v] = ;
}
}
dfs2(root , - , );
dis[root] = ;
for(int k = ; k < ; k++) {
for(int i = ; i <= n ; i++) {
if(par[i][k] <= ) {
par[i][k + ] = ;
}
else {
par[i][k + ] = par[par[i][k]][k];
}
}
}
dfs(root);
for(int i = ; i < m ; i++) {
scanf("%d %d" , &u , &v);
printf("%d\n" , dis[u] + dis[v] - * dis[lca(u , v)]);
}
}
}
树链剖分的LCA:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int MAXN = 5e4 + ;
struct data {
int to , next , cost;
}edge[MAXN << ];
int head[MAXN] , cnt;
int par[MAXN] , dep[MAXN] , top[MAXN] , id[MAXN] , dis[MAXN] , size[MAXN] , son[MAXN]; void init() {
memset(head , - , sizeof(head));
cnt = ;
} inline void add(int u , int v , int cost) {
edge[cnt].to = v;
edge[cnt].next = head[u];
edge[cnt].cost = cost;
head[u] = cnt++;
}
//求size , par , son , dep
void dfs_1(int u , int p , int d) {
par[u] = p , size[u] = , son[u] = u , dep[u] = d;
for(int i = head[u] ; ~i ; i = edge[i].next) {
int v = edge[i].to;
if(v == p)
continue;
dis[v] = dis[u] + edge[i].cost; //离根的距离
dfs_1(v , u , d + );
if(size[v] > size[son[u]]) //取重儿子
son[u] = v;
size[u] += size[v];
}
}
//求top , id
void dfs_2(int u , int p , int t) { //p为父节点 t为链的祖先
top[u] = t; //链的祖先
id[u] = ++cnt; //点的顺序
if(son[u] != u) //重儿子优先
dfs_2(son[u] , u , t);
for(int i = head[u] ; ~i ; i = edge[i].next) {
int v = edge[i].to;
if(v == p || v == son[u])
continue;
dfs_2(v , u , v); //树链重新开始
}
}
//树链剖分求lca的复杂度是(nlognlogn),建议用RMQ求lca
int lca(int u , int v) {
int fu = top[u] , fv = top[v];
while(top[u] != top[v]) { //链是否相同,不同就循环
if(dep[fu] < dep[fv]) { //比较两个链的深度
v = par[fv];
fv = top[fv];
}
else {
u = par[fu];
fu = top[u];
}
}
if(dep[u] >= dep[v]) //在相同的链上
return v;
return u;
} int main()
{
int n , q , u , v , cost , x , y , z , t;
scanf("%d" , &t);
while(t--) {
scanf("%d %d" , &n , &q);
init();
for(int i = ; i < n ; ++i) {
scanf("%d %d %d" , &u , &v , &cost);
add(u , v , cost);
add(v , u , cost);
}
cnt = ;
dfs_1( , , );
dfs_2( , , );
while(q--) {
scanf("%d %d" , &x , &y);
int res = (dis[x] + dis[y] - * dis[lca(x , y)]);
printf("%d\n" , res);
}
}
}
HDU 2586 How far away ? (LCA)的更多相关文章
- HDU 2586 How far away ? (LCA,Tarjan, spfa)
题意:给定N个节点一棵树,现在要求询问任意两点之间的简单路径的距离,其实也就是最短路径距离. 析:用LCA问题的Tarjan算法,利用并查集的优越性,产生把所有的点都储存下来,然后把所有的询问也储存下 ...
- 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
hdu 2586 How far away ?倍增LCA 题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=2586 思路: 针对询问次数多的时候,采取倍增 ...
- HDU 2586 How far away ?【LCA】
任意门:http://acm.hdu.edu.cn/showproblem.php?pid=2586 How far away ? Time Limit: 2000/1000 MS (Java/Oth ...
- 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模板题】
传送门: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) P ...
随机推荐
- oracle视图总结(转)
视图简介: 视图是基于一个表或多个表或视图的逻辑表,本身不包含数据,通过它可以对表里面的数据进行查询和修改.视图基于的表称为基表.视图是存储在数据字典里的一条select语句. 通过创建视图可以提取数 ...
- Asp.Net微信登录-手机网站APP应用
要求:公众号必须先认证,认证费用¥300/年,比较黑 一.微信登录核心代码 //核心代码,没判断异常 1.登录页面 protected void Page_Load(object sender, Ev ...
- hdu 4607 Park Visit(树上最长链)
求树上最长链:两遍搜索. 第一次从树上任意点开始,最远点必然是某一条最长链上的端点u. 第二次从u开始,最远点即该最长链的另一端点. 先在最长链上走,不足再去走支链. 把询问数m错打成n,狠狠wa了一 ...
- 使用java解析和制作二维码
项目结构 文件源码 QR.zip 第一步:导入zxing的两个架包 core.jar和javase.jar 第二步:使用工具类 MatrixToImageWriter.java package uti ...
- UIView 设置alpha后, 子view也随着变化alpha, 解决方法
// _closeContainerBar.alpha = 0.7; _closeContainerBar.backgroundColor = [[UIColor blackColor] ...
- ajax请求总是不成功?浏览器的同源策略和跨域问题详解
场景 码农小明要做一个展示业务数据的大屏给老板看,里面包含了来自自己网站的数据和来自隔壁老王的数据.那么自己网站的数据提供了 http://xiaoming.com/whoami 这样的数据接口隔壁老 ...
- hdu 1505(dp求最大子矩阵)
题意:就是让你求出全由F组成的最大子矩阵. 分析:这是hdu 1506的加强版,只不过这道题变成了2维的,那我们就一行一行的来.具体的分析见1506的博客:http://www.cnblogs.com ...
- 仿网易新闻客户端头条ViewPager嵌套实例
要点: 1.重写组件public boolean onInterceptTouchEvent(MotionEvent event)方法 2.正确使用requestDisallowInterceptTo ...
- [GRYZ]寒假模拟赛
写在前面 这是首次广饶一中的OIERS自编自导,自出自做(zuo)的模拟赛. 鉴于水平气压比较低,机(wei)智(suo)的WMY/XYD/HYXZC就上网FQ下海找了不少水(fei)题,经过他们优( ...
- Tomcat中的线程池StandardThreadExecutor
之所以今天讨论它,因为在motan的的NettyServer中利用它这个线程池可以作为业务线程池,它定制了一个自己的线程池.当然还是基于jdk中的ThreadExecutor中的构造方法和execut ...