牛客编程巅峰赛S2第5场 - 钻石&王者 C Tree III(树的第二直径)

题意:求树的第二直径

思路:树的第二直径一定以树的直径的某一端为端点,用两次dfs求树的直径的两个端点,再对两个端点分别进行dfs求出端点到其他点的距离,把这些距离从大到小排个序,第一第二大的都是直径,第三大的就是第二直径。

思路参考https://blog.csdn.net/qq_43765333/article/details/110454816

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
const int M = 1e6 + 10;
const int inf = 0x3f3f3f3f;

int n, dis[N], maxx, id;
bool vis[N];
vector<int>ans, mp[N];

void dfs(int u, int fa) {
    ans.emplace_back(dis[u]);
    if(maxx < dis[u]) {
        maxx = dis[u];
        id = u;
    }
    int siz = mp[u].size();
    for(int i = 0; i < siz; ++i) {
        int v = mp[u][i];
        if(v == fa) continue;
        dis[v] = dis[u] + 1;
        dfs(v, u);
    }
}

class Solution {
public:
    int tree3(vector<int>& e) {
        n = e.size() + 1;
        for(int i = 2; i <= n; ++i) {
            mp[i].emplace_back(e[i - 2]);
            mp[e[i - 2]].emplace_back(i);
        }
        for(int i = 1; i <= n; ++i) vis[i] = 0;
        for(int i = 1; i <= n; ++i) dis[i] = 0;
        maxx = 0;
        dfs(1, 0);
        ans.clear();
        for(int i = 1; i <= n; ++i) vis[i] = 0;
        for(int i = 1; i <= n; ++i) dis[i] = 0;
        dfs(id, 0);
        for(int i = 1; i <= n; ++i) vis[i] = 0;
        for(int i = 1; i <= n; ++i) dis[i] = 0;
        dfs(id, 0);
        sort(ans.begin(), ans.end(), greater<int>());
        return ans[2];
    }
};

猜你喜欢

转载自blog.csdn.net/weixin_43871207/article/details/110575153