The third week tournament title D

Meaning of the questions:

Repeatedly asked two treesshortest distance.

TLE practice: once for each query shortest run, optimize Dijkstra then with stack complexity approximately \ (O (Q * (n-m +) logM) \) .
\ (100 \) points approach:
using a \ (DIS \) array record root \ (the root \) to the distance of each node, then two trees \ (u, v \) distance is \ (the root \ ) to \ (u \) distance plus \ (root \) to \ (v \) distance minus two times the \ (root \) to \ (lca (u, v) \) distance (can draw FIG appreciated that the inductive ...), i.e.
\ (ans = dis [u]
+ dis [v] -2 * dis [lca (u, v)] \) I use the tree multiplier seeking \ (LCA \) .

Common ancestor ( \ (LCA \) ) refers to a tree or simultaneously with a directed acyclic graph has the \ (V \) and \ (W \) as the deepest node descendants, two common ancestor to all nodes a common ancestor in the furthest away from the root node.

In fact, \ (lca \) template theme, will look at a few of the blog.
Method of seeking can refer to the chiefs of the blog Talking about the recent common ancestor
common ancestor

#include <bits/stdc++.h>
using namespace std;

#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define endl '\n'

typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> pii;

const int maxn  = 75000 + 5;
const int maxm  = 100 + 5;
const int inf   = 0x3f3f3f3f;
const LL  mod   = 1e9 + 7;//19260817
const double pi = acos(-1.0);

int n, q, cnt, x, y, deep[maxn], pre[maxn][20], head[maxn], dis[maxn];

struct node {
    int v, w, next;
} edge[maxn << 1];

void addedge(int u, int v, int w) {
    edge[++cnt].v = v;
    edge[cnt].w = w;
    edge[cnt].next = head[u];
    head[u] = cnt;
}

void dfs(int x, int f) {
    pre[x][0] = f;
    for(int i = head[x]; i; i = edge[i].next) {
        if(edge[i].v != f) {
            deep[edge[i].v] = deep[x] + 1;
            dis[edge[i].v] = dis[x] + edge[i].w;
            dfs(edge[i].v, x);
        }
    }
}

void solve() {
    for(int j = 1; j <= 19; j++)
        for(int i = 1; i <= n; i++)
            pre[i][j] = pre[pre[i][j - 1]][j - 1];
}

int lca(int u, int v) {
    if(deep[u] < deep[v]) swap(u, v);
    int dc = deep[u] - deep[v];
    for(int i = 0; i <= 19; i++) {
        if((1 << i) & dc) u = pre[u][i];
    }
    if(u == v) return u;
    for(int i = 19; ~i; i--) {
        if(pre[u][i] != pre[v][i]) {
            u = pre[u][i];
            v = pre[v][i];
        }
    }
    return pre[u][0];
}

int main() {
    scanf ("%d", &n);
    for (int i = 1, u, v, w; i <= n - 1; i++) {
        scanf ("%d %d %d", &u, &v, &w);
        ++u, ++v;
        addedge(u, v, w), addedge(v, u, w);
    }
    dfs(1, -1);
    solve();
    scanf ("%d", &q);
    while (q--) {
        scanf ("%d %d", &x, &y);
        ++x, ++y;
        printf ("%d\n", dis[x] + dis[y] - 2 * dis[lca(x, y)]);
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/ChaseNo1/p/11366608.html