题意:求树的第二直径
思路:树的第二直径一定以树的直径的某一端为端点,用两次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];
}
};