int lca(int a, int b) { if (dep[a] < dep[b]) { int temp = a; a = b; b = temp; } for (int p = power; p >= 0; p--) { if (dep[stjump[a][p]] >= dep[b]) { a = stjump[a][p]; // 这里使要查询的两个节点处于同一深度 } } if (a == b) return a;
for (int p = power; p >= 0; p--) { if (stjump[a][p] != stjump[b][p]) { a = stjump[a][p]; b = stjump[b][p]; // 使二者的深度与目标深度相差一 } } return stjump[a][0]; }
建图
这里推荐的建图方法是链式前向星,其使用三个数组来查找每个节点延伸出去的边。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
void add(int u, int v, int w) { // u -> v, 权重是w next[cnt] = head[u]; // 现在这条边的上一条边是出发点的头部边 to[cnt] = v; weight[cnt] = w; head[u] = cnt; // 出发点的头部边更新为现在的边 cnt++; }
// 无向图要add两次
for (int i = 1; i <= n; i++) { // i是节点号 for (int ei = head[i]; ei > 0; ei = next[ei]) { // ei是边号 }