必经之路

发布时间 2023-06-05 21:43:06作者: Lumen3ever

必经之路

OJ:https://codefun2000.com/p/P1167

目录

题目大意

给一个n个结点的树,给一条边,要找到所有经过这条边的路径中最长路径的长度,规定每条边的路径长度为1。

题解

可以将树从要求的路径中一分为二,这样就成了两棵树,再分别以这两个结点为两个子树的根节点,找到所有以这两个结点为根的树中最长的路径,然后将两个路径长度相加,最后再加上一开始切割开的那个树枝即可。

可以画图看一下样例:

AC代码

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

const int N = 100010;
int n;
int h[N], e[2 * N], ne[2 * N], idx;

void add(int a, int b) {
    e[idx] = b, ne[idx] = h[a], h[a] = idx++;
}

int dfs(int u, int fa) {
    int res = 0;
    for(int i = h[u]; i != -1; i = ne[i]) {
        int j = e[i];
        if(j == fa) continue;
        res = max(res, dfs(j, u) + 1);
    }
    return res;
}

int main() {
    cin >> n;
    memset(h, -1, sizeof h);
    for(int i = 0; i < n - 1; i++) {
        int a = i + 2;
        int b;
        cin >> b;
        add(a, b);
        add(b, a);
    }
    int x, y;
    cin >> x >> y;
    cout << dfs(y, x) + dfs(x, y) + 1 << '\n';
    return 0;
}

代码实现中要注意这里是双向边,所以边数要开2*N,否则会MLE。