【codevs 2370】小机房的树 | 倍增+LCA
传送门
带权LCA。
太弱了太弱了太弱了衰~~
————————————————————————————————————————————
错误①:
for(int i = 20; i >= 0; i++)
RE!!!!
错误②:
本来想直接把边权加到deep上(果然是蒟蒻
)。
但是!!!
倍增的 deep 不能动,动动脑子就知道了!!!!
另开一个数组,比如下面的 path[] 来记录权值什么的就好了。
注意:特判不能忘!!!!!!!今天又做了一次,忘了特判,WA了一次 :-(
#include <cstdio>
const int MAXN = 50000 * 2 + 7;
int n, m, fa[MAXN][30 + 7], ans, root, path[MAXN];
struct Edge;
struct Node {
Edge *last;
int deep, ma;
// int in;
} node[MAXN];
struct Edge {
Node *from, *to;
Edge *next;
int pow;
Edge (Node * from, Node *to, int pow) : from(from), to(to), next(from->last), pow(pow) {}
};
void addE(int x, int y, int z) {
node[x].last = new Edge(node + x, node + y, z);
node[y].last = new Edge(node + y, node + x, z);
}
void dfs(int s) {
for (int i = 1; i <= 30; i++) fa[s][i] = fa[fa[s][i - 1]][i - 1];
for (Edge *e = node[s].last; e; e = e->next) {
if (!e->to->deep && e->to->ma) {
e->to->deep = node[s].deep + 1;
path[e->to->ma] = path[s] + e->pow;
fa[e->to->ma][0] = s;
dfs(e->to->ma);
}
}
}
int lca(int x, int y) {
if (node[x].deep < node[y].deep) {
int t = x;
x = y, y = t;;
}
for (int i = 0; i <= 30; i++)
if ((node[x].deep - node[y].deep) >> i & 1) x = fa[x][i];
if (x == y) return x; // !!!!!!!!!!!!!!!!!!!!!
for (int i = 30; i >= 0; i--)
if (fa[x][i] != fa[y][i])
x = fa[x][i], y = fa[y][i];
return fa[x][0];
}
int main() {
scanf("%d", &n);
for (int i = 1; i <= n; i++) node[i].ma = i;
for (int i = 1, x, y, z; i < n; i++) scanf("%d%d%d", &x, &y, &z), addE(x, y, z);
// for (int i = 1; i <= n; i++)
// if (node[i].in == 1) {
// root = i;
// break;
// }
// node[root].deep = 0;
// fa[root][0] = root;
node[0].deep = 1;
fa[root][0] = 0;
dfs(0);
scanf("%d", &m);
for (int i = 1, x, y; i <= m; i++) {
ans = 0;
scanf("%d%d", &x, &y);
// printf("lca(%d, %d) = %d\n", x, y, lca(x, y));
ans += path[x] + path[y] - path[lca(x, y)] * 2;
printf("%d\n", ans);
}
return 0;
}

浙公网安备 33010602011771号