必经之路

必经之路

前言

最近碰到一个专门制作大厂真题模拟题的网站,最近一直在上面刷题。今天来每日一题,这是今年美团0408的一道题。稍微整理了一下自己的思路。下面是题目:

目录

题目大意

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

这题的评测地址:https://codefun2000.com/p/P1167

题解

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

可以画图看一下样例:

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。

posted @ 2023-06-05 21:37  Lumen3ever  阅读(34)  评论(0)    收藏  举报