P2491 [SDOI2011] Tree diameter + ruler selection

Title

Portal P2491 [SDOI2011] Fire

answer

Let the two end points of the diameter be u, vu, vu ,v . According to the longest diameter, anything fromu, pu, pu ,The subtree of the diameter that branches off between p , and its furthest point is the same asppthe distance of p will not be greater thanppp givenuuThe distance of u is farther.

Establish a pivot on the bifurcation of the diameter of the tree, and set the intersection of the path and the diameter of the tree as ppp , thenppp to the diameter endpointu, vu, vu ,At least one path of v is not covered. According to the longest diameter of the tree, the maximum distance from other nodes to the selected path will not be changed at this time.

Then just consider building a hub on the diameter of the tree. mx [i] mx[i]m x [ i ] represents the nodeiion the diameter of the treei The distance of the farthest point that can be reached without passing through other nodes on the diameter. Let the left and right end points of the path on the diameter satisfying the conditions bel, rl, rl,r,则答案为 max ⁡ ( max ⁡ i ∈ [ l , r ] { m x [ i ] } , d i s ( u , l ) , d i s ( r , v ) ) \max\Big(\max_{i\in [l,r]}\{mx[i]\},dis(u,l),dis(r,v)\Big) max(i[l,r]max{ mx[i]},d i s ( u ,l),dis(r,v ) ) According to the longest diameter of the tree, the above formula can be simplified tomax ⁡ (max ⁡ i ∈ [u, v] {mx [i]}, dis (u, l), dis (r, v)) \max\Big(\max_{i\in [u,v]}\{mx[i]\},dis(u,l),dis(r,v)\Big)max(i [ u , v ]max{ mx[i]},d i s ( u ,l),dis(r,v ) ) Use the ruler method to update the answer.

#include <bits/stdc++.h>
using namespace std;
const int maxn = 300005, maxm = maxn << 1, inf = 0x3f3f3f3f;
int N, S, num, ds[maxn], fa[maxn], mx[maxn], rec[maxn];
int tot, head[maxn], to[maxm], cost[maxm], nxt[maxm];
bool in[maxn];

inline void add(int x, int y, int z)
{
    
    
    to[++tot] = y, cost[tot] = z, nxt[tot] = head[x], head[x] = tot;
}

void dfs(int x, int f, int w, int &t)
{
    
    
    ds[x] = w, fa[x] = f;
    if (ds[x] >= ds[t])
        t = x;
    for (int i = head[x]; i; i = nxt[i])
    {
    
    
        int y = to[i], z = cost[i];
        if (y != f)
            dfs(y, x, w + z, t);
    }
}

void dfs2(int x, int f, int w)
{
    
    
    mx[x] = w;
    for (int i = head[x]; i; i = nxt[i])
    {
    
    
        int y = to[i], z = cost[i];
        if (y != f && !in[y])
            dfs2(y, x, w + z), mx[x] = max(mx[x], mx[y]);
    }
}

int main()
{
    
    
    scanf("%d%d", &N, &S);
    for (int i = 1, x, y, z; i < N; ++i)
        scanf("%d%d%d", &x, &y, &z), add(x, y, z), add(y, x, z);
    int s = 1, t = 0;
    dfs(s, 0, 0, t);
    s = t, t = 0;
    dfs(s, 0, 0, t);
    int dm = ds[t];
    for (int i = t; i; i = fa[i])
        rec[++num] = i, in[i] = 1;
    for (int i = 1; i <= num; ++i)
        dfs2(rec[i], 0, 0);
    int a = 0, res = inf;
    for (int i = 1; i <= num; ++i)
        a = max(a, mx[rec[i]]);
    int l = 1, r = 1;
    for (;;)
    {
    
    
        while (r + 1 <= num && ds[rec[l]] - ds[rec[r + 1]] <= S)
            ++r;
        res = min(res, max(a, max(dm - ds[rec[l]], ds[rec[r]])));
        if (r == num)
            break;
        ++l;
    }
    printf("%d\n", res);
    return 0;
}

Guess you like

Origin blog.csdn.net/neweryyy/article/details/114805735