原题链接:http://acm.uestc.edu.cn/#/problem/show/92

题意:

给你一棵树,然后在树上连接一条边。现在有若干次询问,每次问你两个点(u,v)之间的距离在加那条边之后减小了多少。

题解:

对于那条加入的边,只有两种情况,要么走,要么不走。不走的距离就是$dis[u]+dis[v]-2*dis[LCA(u,v)]$,其中$dis$表示点到根节点的距离,LCA表示最近公共祖先。现在考虑走的情况:设加入的那条边是$(a,b)$,边权是c,那么答案显然是:

$$min(DIS(a,u)+DIS(b,v)+c,DIS(a,v)+DIS(b,u)+c)$$

其中DIS表示两点间在树上的最短距离。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<vector>
#include<algorithm>
#define MAX_N 100005
#define MAX_D 22
using namespace std; struct edge {
public:
int to, cost; edge(int t, int c) : to(t), cost(c) { } edge() { }
}; vector<edge> G[MAX_N]; int n,q; int ancestor[MAX_N][MAX_D];
int depth[MAX_N]; int dis[MAX_N]; void init(){
memset(dis,,sizeof(dis));
memset(ancestor,,sizeof(ancestor));
memset(depth,,sizeof(depth));
for(int i=;i<=n;i++)G[i].clear();
} void dfs(int u,int p) {
for (int i = ; i < G[u].size(); i++) {
int v = G[u][i].to;
if (v == p)continue;
dis[v]=dis[u]+G[u][i].cost;
depth[v] = depth[u] + ;
ancestor[v][] = u;
dfs(v, u);
}
} void getAncestor() {
for (int j = ; j < MAX_D; j++)
for (int i = ; i <= n; i++)
ancestor[i][j] = ancestor[ancestor[i][j - ]][j - ];
} int LCA(int u,int v) {
if (depth[u] < depth[v])swap(u, v);
for (int i = MAX_D - ; i >= ; i--) {
if (depth[ancestor[u][i]] >= depth[v]) {
u = ancestor[u][i];
if (depth[u] == depth[v])break;
}
}
if (u == v)return u;
for (int i = MAX_D - ; i >= ; i--) {
if (ancestor[u][i] != ancestor[v][i]) {
u = ancestor[u][i];
v = ancestor[v][i];
}
}
return ancestor[u][];
} int getDis(int u,int v) {
int L = LCA(u, v);
return dis[u] + dis[v] - * dis[L];
} int T;
int cas=; int main() {
cin >> T;
while (T--) {
printf("Case #%d:\n", ++cas);
scanf("%d%d", &n, &q);
init();
for (int i = ; i < n - ; i++) {
int u, v, c;
scanf("%d%d%d", &u, &v, &c);
G[u].push_back(edge(v, c));
G[v].push_back(edge(u, c));
}
int x, y, z;
scanf("%d%d%d", &x, &y, &z);
dfs(, );
getAncestor();
while (q--) {
int u, v;
scanf("%d%d", &u, &v);
int tmp, ans;
ans = tmp = getDis(u, v);
ans = min(ans, getDis(u, x) + getDis(y, v) + z);
ans = min(ans, getDis(u, y) + getDis(x, v) + z);
printf("%d\n", tmp - ans);
}
}
return ;
}

CDOJ 92 Journey LCA乱搞的更多相关文章

  1. CDOJ 92 Journey(LCA&RMQ)

    题目连接:http://acm.uestc.edu.cn/#/problem/show/92 题意:给定一棵树,最后给加一条边,给定Q次查询,每次查询加上最后一条边之后是否比不加这条边要近,如果近的话 ...

  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. 洛谷 P1600 天天爱跑步(LCA+乱搞)

    传送门 我们把每一条路径拆成$u->lca$和$lca->v$的路径 先考虑$u->lca$,如果这条路径会对路径上的某一个点产生贡献,那么满足$dep[u]-dep[x]=w[x] ...

  5. cdoj Dividing Numbers 乱搞记忆化搜索

    //真tm是乱搞 但是(乱搞的)思想很重要 解:大概就是记忆化搜索,但是原数据范围太大,不可能记下所有的情况的答案,于是我们就在记下小范围内的答案,当dfs落入这个记忆范围后,就不进一步搜索,直接返回 ...

  6. CF809E Surprise me!(莫比乌斯反演+Dp(乱搞?))

    题目大意: 给你一棵树,树上的点编号为\(1-n\).选两个点\(i.j\),能得到的得分是\(\phi(a_i*a_j)*dis(i,j)\),其中\(dis(i,j)\)表示\(a\)到\(b\) ...

  7. 学渣乱搞系列之Tarjan模板合集

    学渣乱搞系列之Tarjan模板合集 by 狂徒归来 一.求强连通子图 #include <iostream> #include <cstdio> #include <cs ...

  8. [WC2018]通道(乱搞,迭代)

    [洛谷题面]https://www.luogu.org/problemnew/show/P4221 这个题以及[CTSC2018 暴力写挂]都有类似的乱搞做法能通过考场数据. 具体搞法就是随一个起点, ...

  9. URAL 1827 Indigenous Wars(排序、乱搞)

    题意:给一个长度为n数组{a[i]}.有m个操作Ti,Si,Li表示找以Ti值结束,以Si值开始,长度为Li的连续子串.找到后,将区间的答案值设为1.一开始答案值全部为0.最后输出n个答案值. 好久没 ...

随机推荐

  1. STM32CUBEMX入门学习笔记1:软件的简单介绍

    STM32CUBEMX是ST公司设计的一款免费软件,软件可以通过其官网下载.现在已经下载到.通过STM32CUBEMX可以完成从单片机选型,程序初始化,中断配置……工作.并生成对应的"HAL ...

  2. 第二章 jquery的dom操作

    三个方面    dom核心,html-dom和css-dom 一. 1.dom core核心 document.getElementsByTagName("form")  获取表单 ...

  3. Leetcode 480.滑动窗口中位数

    滑动窗口中位数 中位数是有序序列最中间的那个数.如果序列的大小是偶数,则没有最中间的数:此时中位数是最中间的两个数的平均数. 例如: [2,3,4],中位数是 3 [2,3],中位数是 (2 + 3) ...

  4. ubuntu14.04 不能关机,一直停在关机界面

    1.emotion: 最近在使用Ubuntu14.04 LTS时,输入shutdown -h now之后,Ubuntu就一直停在关机界面,始终不能shutdown,不得不手动按下电源button.忍受 ...

  5. Linux删除非空目录的方法

    rmdir 无法删除非空目录. rm -rf 可以递归,强制,删除目录

  6. Difference between git remote add and git clone

    http://stackoverflow.com/questions/4855561/difference-between-git-remote-add-and-git-clone git remot ...

  7. 【bzoj2085】[Poi2010]Hamsters Hash+倍增Floyd

    题目描述 Tz养了一群仓鼠,他们都有英文小写的名字,现在Tz想用一个字母序列来表示他们的名字,只要他们的名字是字母序列中的一个子串就算,出现多次可以重复计算.现在Tz想好了要出现多少个名字,请你求出最 ...

  8. Bind Enum To DropDownList ?

    0. 准备测试数据 0.1 : 枚举 using System; using System.Collections.Generic; using System.Linq; using System.W ...

  9. JavaScript阻止冒泡和取消事件默认行为

    //功能:停止事件冒泡 function stopBubble(e) { if ( e && e.stopPropagation ) { e.stopPropagation(); } ...

  10. linux tomcat安装(二)

    安装步骤: 1.下载 Tomcat 下载 apache-tomcat-7.0.69.tar.gz(官方网址:http://tomcat.apache.org/) 2.解压 Tomcat 解压 apac ...