题目连接: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. KVO初探

    一,概述 KVO,即:Key-Value Observing,它提供一种机制,当指定的对象的属性被修改后,则对象就会接受到通知.简单的说就是每次指定的被观察的对象的属性被修改后,KVO就会自动通知相应 ...

  2. api1

    http://www.android-doc.com/reference/android/app/Fragment.html

  3. sql restore mode

    refer : https://msdn.microsoft.com/en-us/library/ms189272.aspx SELECT name, recovery_model_desc FROM ...

  4. ARM单片机的头文件如何用结构体定义地址

    下面我们以ARM Cortex-M0内核单片机LPC1114的头文件lpc11xx.h文件进行说明. 1.先说两句 lpc11xx.h文件是lpc11xx系列单片机包含的头文件.这个文件的作用和51单 ...

  5. Spring的OpenEntityManagerInViewFilter

    在Java Web项目中使用Hibernate经常会遇到LazyInitializationException .这是因为controller和model层(java代码)将通过JPA的一些启用了延迟 ...

  6. Unity NGUI制作scroll view

    unity版本:4.5 NGUI版本:3.6.5 参考链接:http://blog.csdn.net/monzart7an/article/details/23878505,作者:CSDN 冬菊子   ...

  7. Unity 通过Animation实现控件位置的转换

    Unity版本:4.5.1 NGUI版本:3.6.5 参考链接:http://blog.csdn.net/unity3d_xyz/article/details/23035521,作者:CSDN in ...

  8. 使用 libevent 和 libev 提高网络应用性能

    使用 libevent 和 libev 提高网络应用性能 Martin C. Brown, 作家, Freelance 简介: 构建现代的服务器应用程序需要以某种方法同时接收数百.数千甚至数万个事件, ...

  9. 线性代数(矩阵乘法):NOI 2007 生成树计数

    这道题就是深搜矩阵,再快速幂. #include <iostream> #include <cstring> #include <cstdio> #include ...

  10. ScrollView自动滑到底部

    // 自动滑动到底部 mScrollView.post(new Runnable() { @Override public void run() { mScrollView.fullScroll(Sc ...