题目连接: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. YII 小部件 解决多选按钮和单选按钮不在同一水平上 'separator'=>'&nbsp;'

    主要是添加separator属性(这里)$hoddy,$sex在控制器里面定义的数组,然后render传过来的 <td>          <?php echo $form-> ...

  2. 项目知识点.Part2

    1. 取消collectionView头视图重叠情况:以下两种情况效果一样 但是有一点点bug 每次remove之后 需要把视图刷到上面才会显示(后续会改进方法) for (UIView *view ...

  3. 在Site Settings下找不到Navigation标签

    有时候我们可能找不到Navigation标签, 仅仅在Look and Feel下面看到"Quick launch" 如何才能找到我们想要的"Navigation&quo ...

  4. cocos creater 简单的跳跃动作。

    因为最近一段时间有打算做一个2D游戏的想法,就顺便学习了一下cocos,很惊异的它的脚本编写语言竟然支持js,正好以前对js有一定的了解,就临时拿起来了. 这是来自官方的一个实例,不过在参考过程中,发 ...

  5. IOS--UISlider的使用方法

    IOS--UISlider的使用方法 // UISlider的常用方法 UISlider *oneSlider = [[UISlider alloc] init]; // 最常用 oneSlider. ...

  6. Node.js RESTful API

    什么是REST架构? REST表示代表性状态传输.REST是一种基于Web标准的架构,并使用HTTP协议. 它都是围绕着资源,其中每一个组件是资源和一个资源是由一个共同的接口使用HTTP的标准方法获得 ...

  7. BZOJ 1048 分割矩阵

    Description 将一个a*b的数字矩阵进行如下分割:将原矩阵沿某一条直线分割成两个矩阵,再将生成的两个矩阵继续如此分割(当然也可以只分割其中的一个),这样分割了(n-1)次后,原矩阵被分割成了 ...

  8. MongoDB入门简介

    MongoDB入门简介 http://blog.csdn.net/lolinzhang/article/details/4353699 有关于MongoDB的资料现在较少,且大多为英文网站,以上内容大 ...

  9. Babelfish

    Time Limit: 1000MS Memory limit: 65536K 题目描述You have just moved from Waterloo to a big city. The peo ...

  10. 1.Repeater控件

    在用到数据库数据并且要逐条显示时,就需要用到repeater\listview等这样的数据库控件进行动态的显示数据. Repeater相当于foreach的功能,用于对绑定数据源中的数据进行遍历显示, ...