一次dfs就可以求解:
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 100010,M = 2 * N;
int h[N],e[M],ne[M],idx;
int n,m,res;
void add(int a,int b){
e[idx] = b;
ne[idx] = h[a];
h[a] = idx++;
}
int dfs(int u){
int a = 0,b = 0;//a、b分别表示u能到的叶节点的最远长度和次远长度
for(int i = h[u];i != -1;i = ne[i]){
int j = e[i];
int d = dfs(j);
if(d >= a) b = a,a = d;
else if (d > b) b = d;
}
res = max(res,a + b);
return a + 1; // j到u还有一条边
}
int main(){
memset(h,-1,sizeof h);
cin >> n >> m;
for(int i = 2;i <= n + m;i++){
int p;
cin >> p;
add(p,i);
}
dfs(1);
cout << res << endl;
return 0;
}
两次dfs求解:
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
const int N = 20010,M = 2 * N;
int h[N],e[M],ne[M],idx;
int d[N];
int n,m;
void add(int a,int b){
e[idx] = b;
ne[idx] = h[a];
h[a] = idx++;
}
int bfs(int u){
memset(d,-1,sizeof d);
d[u] = 0;
queue<int> q;
q.push(u);
while(q.size()){
int t = q.front();
q.pop();
for(int i = h[t];i != -1;i = ne[i]){
int j = e[i];
if(d[j] == -1){
d[j] = d[t] + 1;
q.push(j);
}
}
}
int res = 1;
for(int i = 2;i <= n + m;i++){
if(d[res] < d[i]){
res = i;
}
}
return res;
}
int main(){
memset(h,-1,sizeof h);
cin >> n >> m;
for(int i = 2;i <= n + m;i++){
int p;
cin >> p;
add(p,i),add(i,p);
}
int l = bfs(1);
int r = bfs(l);
cout << d[r] << endl;
return 0;
}