LCA UESTC 92 Journey
题意:先给一棵树,然后有一条额外的边,问u走到v从现在最短的路走和原来不加边走的路节省了多少距离
分析:首先跑不加边的树的LCA,这样能求出任意两点的距离,那么现在x和y多连了一条边,如果能节省路程那一定是走了xy这条边,那么暴力枚举组合,比如求u到v,新边xy,ans = min (ans, min (dux + dxy + dyv, duy + dyx + dxv))
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <vector>
#include <queue>
using namespace std; typedef long long ll;
const int N = 1e5 + 10;
const int D = 20;
const int INF = 0x3f3f3f3f;
struct Edge {
int v, w, nex;
Edge (int v = 0, int w = 0, int nex = 0) : v (v), w (w), nex (nex) {}
}edge[N<<1];
int head[N], dep[N], rt[D][N];
int d[N];
int n, q, e;
int x, y, cost; void init(void) {
memset (head, -1, sizeof (head));
e = 0;
} void add_edge(int u, int v, int w) {
edge[e] = Edge (v, w, head[u]);
head[u] = e++;
} void DFS(int u, int fa, int deep, int len) {
dep[u] = deep; d[u] = len; rt[0][u] = fa;
for (int i=head[u]; ~i; i=edge[i].nex) {
int v = edge[i].v, w = edge[i].w;
if (v == fa) continue;
DFS (v, u, deep + 1, len + w);
}
} int LCA(int u, int v) {
if (dep[u] < dep[v]) swap (u, v);
for (int i=0; i<D; ++i) {
if ((dep[u] - dep[v]) >> i & 1) {
u = rt[i][u];
}
}
if (u == v) return u;
for (int i=D-1; i>=0; --i) {
if (rt[i][u] != rt[i][v]) {
u = rt[i][u];
v = rt[i][v];
}
}
return rt[0][u];
} int solve(int u, int v) {
int lca = LCA (u, v);
int ans = d[u] + d[v] - d[lca] * 2; int lca1 = LCA (u, x);
int dux = d[u] + d[x] - d[lca1] * 2; int lca2 = LCA (u, y);
int duy = d[u] + d[y] - d[lca2] * 2; int lca3 = LCA (v, x);
int dvx = d[v] + d[x] - d[lca3] * 2; int lca4 = LCA (v, y);
int dvy = d[v] + d[y] - d[lca4] * 2; int mn = min (dux + dvy + cost, duy + dvx + cost);
if (mn > ans) return 0;
else return ans - mn;
} int main(void) {
int T, cas = 0; scanf ("%d", &T);
while (T--) {
init ();
scanf ("%d%d", &n, &q);
for (int u, v, w, i=1; i<n; ++i) {
scanf ("%d%d%d", &u, &v, &w);
add_edge (u, v, w);
add_edge (v, u, w);
}
scanf ("%d%d%d", &x, &y, &cost);
DFS (1, -1, 0, 0);
for (int i=1; i<D; ++i) {
for (int j=1; j<=n; ++j) {
rt[i][j] = rt[i-1][j] == -1 ? -1 : rt[i-1][rt[i-1][j]];
}
}
printf ("Case #%d:\n", ++cas);
for (int u, v, i=1; i<=q; ++i) {
scanf ("%d%d", &u, &v);
printf ("%d\n", solve (u, v));
}
} return 0;
}
LCA UESTC 92 Journey的更多相关文章
- cdoj 92 Journey tarjan/lca 树上点对距离
Journey Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://acm.uestc.edu.cn/#/problem/show/92 Descri ...
- CDOJ 92 Journey(LCA&RMQ)
题目连接:http://acm.uestc.edu.cn/#/problem/show/92 题意:给定一棵树,最后给加一条边,给定Q次查询,每次查询加上最后一条边之后是否比不加这条边要近,如果近的话 ...
- CDOJ 92 Journey LCA乱搞
原题链接:http://acm.uestc.edu.cn/#/problem/show/92 题意: 给你一棵树,然后在树上连接一条边.现在有若干次询问,每次问你两个点(u,v)之间的距离在加那条边之 ...
- UESTC 1717 Journey(DFS+LCA)(Sichuan State Programming Contest 2012)
Description Bob has traveled to byteland, he find the N cities in byteland formed a tree structure, ...
- CDOJ 92 – Journey 【LCA】
[题意]给出一棵树,有n个点(2≤N≤105),每条边有权值,现在打算新修一条路径,给出新路径u的起点v,终点和权值,下面给出Q(1≤Q≤105)个询问(a,b)问如果都按照最短路径走,从a到b节省了 ...
- POJ 3278:The merchant(LCA&DP)
The merchant Time Limit: 3000MS Memory Limit: 65536K Total Submissions: 6864 Accepted: 2375 Desc ...
- UESTC(LCA应用:求两点之间的距离)
Journey Time Limit: 15000/3000MS (Java/Others) Memory Limit: 65535/65535KB (Java/Others) Bob has ...
- UESTC 912 树上的距离 --LCA+RMQ+树状数组
1.易知,树上两点的距离dis[u][v] = D[u]+D[v]-2*D[lca(u,v)] (D为节点到根节点的距离) 2.某条边<u,v>权值一旦改变,将会影响所有以v为根的子树上的 ...
- POJ 1986 Distance Queries / UESTC 256 Distance Queries / CJOJ 1129 【USACO】距离咨询(最近公共祖先)
POJ 1986 Distance Queries / UESTC 256 Distance Queries / CJOJ 1129 [USACO]距离咨询(最近公共祖先) Description F ...
随机推荐
- 【 D3.js 进阶系列 — 1.2 】 读取 CSV 文件时乱码的解决方法
在 D3 中使用 d3.csv 读取 CSV 文件时,有时会出现乱码问题. 怎么解决呢? 1. 乱码问题 使用 d3.csv 读取 xxx.csv 文件时.假设 xxx.csv 文件使用的是 UTF- ...
- 增加实时性的异常url检测
技能点: 搭建服务器.restfulapi 在py脚本中调取另一个脚本执行
- iOS 视图在不同View之间的切换(对于convertRect:函数的一些理解)
可以通过以下函数完成坐标体系在不同View之间的切换,如下面是完成当前View向ParentView坐标的转换(一个矩阵转换)CGRect parentRect = [currentView conv ...
- 为了cider,尝试emacs的坑
https://github.com/clojure-emacs/cider http://clojure-doc.org/articles/tutorials/emacs.html emacs通过b ...
- Jackson序列化和反序列化
1,下载Jackson工具包(jackson-core-2.2.3.jar jackson-annotations-2.2.3.jar jackson-databind-2.2.3.jar ) j ...
- Oracle:通过dbv查看数据文件是否有坏块
我们备份的数据文件,可以通过oacle自带的dbv工具来查看是否是好的. 下面实验如下: 环境:oracle10.2.0.1 1.检查数据文件是否有坏块 [oracle@app orcl]$ dbv ...
- CodeForces-380C:Sereja and Brackets(线段树与括号序列)
Sereja has a bracket sequence s1, s2, ..., sn, or, in other words, a string s of length n, consistin ...
- 频繁GC会造成卡顿
频繁GC会造成卡顿 https://www.cnblogs.com/qcloud1001/p/9525078.html 一款app除了要有令人惊叹的功能和令人发指交互之外,在性能上也应该追求丝滑的要求 ...
- make的link_directories命令不起作用
按照<CMake Practice>中第六章的设置,采用include_directories命令去寻找共享库的路径,src/CMakeLists.txt如下: ADD_EXECUTABL ...
- VS2010中编写x64汇编的具体方法
编写涉及系统特性的一些底层程序,特别是ShellCode,不可避免地要采用直接编写汇编代码的方式. 在目标平台为x86模式时,可以直接使用内联汇编,这个很多人都比较熟悉了,也非常地方便. 但是当目标平 ...