题目连接:http://acm.uestc.edu.cn/#/problem/show/92

题意:给定一棵树,最后给加一条边,给定Q次查询,每次查询加上最后一条边之后是否比不加这条边要近,如果近的话,输出近多少,否则输出0

思路:没加最后一条边之前两点之间的距离是dis(u) + dis(v) - 2*dis(lca(u, v)); 加上之后就是必须要经过这两个点。(假设最后添加的一条边的端点为x和y,权值为w)min(dis(u, x) + dis(v, y) + w, dis(u, y) + dis(v, x) + w)

代码如下:

/*************************************************************************
> File Name: 4.cpp
> Author: Howe_Young
> Mail: 1013410795@qq.com
> Created Time: 2015年10月08日 星期四 19时53分38秒
************************************************************************/ #include <cstdio>
#include <iostream>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <algorithm> using namespace std;
typedef long long ll;
const int maxn = 1e5 + ;
struct Edge {
int to, next, w;
}edge[maxn<<];
int tot, head[maxn];
int cnt;
int Euler[maxn<<];
int R[maxn];
int dis[maxn<<];
int dep[maxn<<];
int dp[maxn<<][];
void init()
{
cnt = ;
tot = ;
memset(head, -, sizeof(head));
}
void addedge(int u, int v, int w)
{
edge[tot].to = v;
edge[tot].w = w;
edge[tot].next = head[u];
head[u] = tot++;
}
void dfs(int u, int fa, int depth, int dist)
{
Euler[++cnt] = u;
R[u] = cnt;
dep[cnt] = depth;
dis[cnt] = dist;
for (int i = head[u]; i != -; i = edge[i].next)
{
int v = edge[i].to;
if (v == fa) continue;
dfs(v, u, depth + , dist + edge[i].w);
Euler[++cnt] = u;
dep[cnt] = depth;
dis[cnt] = dist;
}
} void RMQ(int n)
{
for (int i = ; i <= n; i++) dp[i][] = i;
int m = log2(n);
for (int j = ; j <= m; j++)
for (int i = ; i + ( << j) - <= n; i++)
dp[i][j] = dep[dp[i][j - ]] < dep[dp[i + ( << (j - ))][j - ]] ? dp[i][j - ] : dp[i + ( << (j - ))][j - ];
}
int getLCA(int u, int v)
{
if (u == v) return v;
int l = R[u], r = R[v];
if (l > r) swap(l, r);
int k = log2(r - l + );
int lca = dep[dp[l][k]] < dep[dp[r - ( << k) + ][k]] ? dp[l][k] : dp[r - ( << k) + ][k];
return Euler[lca];
}
int getdist(int u, int v)
{
if (u == v) return ;
int l = R[u], r = R[v];
int lca = getLCA(u, v);
return dis[l] + dis[r] - * dis[R[lca]];
}
int main()
{
int T, kase = ;
scanf("%d", &T);
while (T--)
{
init();
int n, Q;
int u, v, w;
scanf("%d %d", &n, &Q);
for (int i = ; i < n; i++)
{
scanf("%d %d %d", &u, &v, &w);
addedge(u, v, w);
addedge(v, u, w);
}
scanf("%d %d %d", &u, &v, &w);
dfs(, , , );
RMQ(cnt);
printf("Case #%d:\n", ++kase);
while (Q--)
{
int a, b;
scanf("%d %d", &a, &b);
int dis1 = getdist(a, b);
int dis2 = min(getdist(a, u) + getdist(v, b) + w, getdist(a, v) + getdist(u, b) + w);
if (dis1 > dis2)
printf("%d\n", dis1 - dis2);
else
printf("0\n");
}
}
return ;
}

CDOJ 92 Journey(LCA&RMQ)的更多相关文章

  1. CDOJ 92 Journey LCA乱搞

    原题链接:http://acm.uestc.edu.cn/#/problem/show/92 题意: 给你一棵树,然后在树上连接一条边.现在有若干次询问,每次问你两个点(u,v)之间的距离在加那条边之 ...

  2. cdoj 92 Journey tarjan/lca 树上点对距离

    Journey Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/problem/show/92 Descri ...

  3. CDOJ 92 – Journey 【LCA】

    [题意]给出一棵树,有n个点(2≤N≤105),每条边有权值,现在打算新修一条路径,给出新路径u的起点v,终点和权值,下面给出Q(1≤Q≤105)个询问(a,b)问如果都按照最短路径走,从a到b节省了 ...

  4. 【Homework】LCA&RMQ

    我校是神校,作业竟然选自POJ,难道不知道“珍爱生命 勿刷POJ”么? 所有注明模板题的我都十分傲娇地没有打,于是只打了6道题(其实模板题以前应该打过一部分但懒得找)(不过感觉我模板还是不够溜要找个时 ...

  5. POJ 2763 (LCA +RMQ+树状数组 || 树链部分) 查询两点距离+修改边权

    题意: 知道了一颗有  n 个节点的树和树上每条边的权值,对应两种操作: 0 x        输出 当前节点到 x节点的最短距离,并移动到 x 节点位置 1 x val   把第 x 条边的权值改为 ...

  6. 算法详解(LCA&RMQ&tarjan)补坑啦!完结撒花(。◕ˇ∀ˇ◕)

    首先,众所周知,求LCA共有3种算法(树剖就不说了,太高级,以后再学..). 1.树上倍增(ST表优化) 2.RMQ&时间戳(ST表优化) 3.tarjan(离线算法)不讲..(后面补坑啦!) ...

  7. LCA UESTC 92 Journey

    题目传送门 题意:先给一棵树,然后有一条额外的边,问u走到v从现在最短的路走和原来不加边走的路节省了多少距离 分析:首先跑不加边的树的LCA,这样能求出任意两点的距离,那么现在x和y多连了一条边,如果 ...

  8. UESTC 912 树上的距离 --LCA+RMQ+树状数组

    1.易知,树上两点的距离dis[u][v] = D[u]+D[v]-2*D[lca(u,v)] (D为节点到根节点的距离) 2.某条边<u,v>权值一旦改变,将会影响所有以v为根的子树上的 ...

  9. [LCA & RMQ] [NOIP2013] 货车运输

    首先看到这题, 由于要最大, 肯定是求最大生成树 那么 o(n2) dfs 求任意点对之间的最小边是可以想到的 但是看看数据范围肯定TLE 于是暴力出来咯, 不过要注意query的时候判断的时候要 m ...

随机推荐

  1. 关于Redis的知识汇总[转]

    1. Overview 1.1 资料 <The Little Redis Book> ,最好的入门小册子,可以先于一切文档之前看,免费. 作者Antirez的博客,Antirez维护的Re ...

  2. 《python学习手册》之一——程序运行

    Python解释器执行Python代码时候,大概经历如下几个阶段:(1) 加载代码文件 (2)翻译成AST (3)生成bytecode(.pyc文件,与编译的python版本有关).可以使用pytho ...

  3. 2661: [BeiJing wc2012]连连看

    Description 凡是考智商的题里面总会有这么一种消除游戏.不过现在面对的这关连连看可不是QQ游戏里那种考眼力的游戏.我们的规则是,给出一个闭区间[a,b]中的全部整数,如果其中某两个数x,y( ...

  4. linux主要目录的作用

    手动敲一遍.算是加强记忆吧~ /:文件系统的入口,也是最高一级的目录 /bin:最基本的且着急用户和普通用户都可以使用的命令放在此目录下,如:ls.cp等 /boot:存放Linux的内核及引导系统所 ...

  5. Eclipse中查找接口实现类快捷键

    就是点击某个接口某个方法名字的时候,直接跳到它的某个实现类里面,一般我们习惯对着那个接口的方法按F3,但是这会直接跳到接口类的源码中,那么呵呵,我们换一个ctrl+T 然后自己选择一下实现类就进去了. ...

  6. hdu 5063 Operation the Sequence

    http://acm.hdu.edu.cn/showproblem.php?pid=5063 思路:因为3查询最多50,所以可以在查询的时候逆操作找到原来的位置,然后再求查询的值. #include ...

  7. C# 绘图对象 流对象 响应对象关系

  8. java学习之查找

    在一组数据当中我们取出一个我们想要的数据的过程,谓之查找. 1.简单查找: 需求:在一组数据当中找到你想要的一个数据,并且返回该数据在数组当中的索引. 思路:循环遍历整个数组,然后拿各个元素与所要找出 ...

  9. SVN服务器搭建(与apache整合)

    一.SVN介绍 SVN是一个版本控制工具,Subversion的版本库(repository),就是位于服务器,统一管理和储存数据的地方. 二.SVN数据存储方式 在Subversion中,版本库的数 ...

  10. 字符串[未AC](后缀自动机):HEOI 2016 str

    超级恶心,先后用set维护right,再用主席树维护,全部超时,本地测是AC的.放心,BZOJ上还是1S限制,貌似只有常数优化到一定境界的人才能AC吧. 总之我是精神胜利了哦耶QAQ #include ...