实际上是给你多颗树,让你用树中结点组成尽可能少的集合,其中同一颗树的结点不能放入同一个集合,思路是每次把树中每一个入度为0的结点挑出来组成一个集合,并且把这个集合中每个结点指向的结点的入度减少,然后把这个新集合中的结点从树中删除即可,按此算法做下去,直到所有树变为空树。
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <stack>
using namespace std;
#define MAX 2005
#define ll long long
#define INF 0x3f3f3f3f
int a[MAX];
vector<int> G[MAX];
int main()
{
int n,p;
cin >> n;
for(int i = 1;i <= n;++i){
scanf("%d",&p);
if(p != -1)
a[p]++,G[i].push_back(p);
}
queue<int> st;
for(int i = 1;i <= n;++i){
if(a[i] == 0){
st.push(i);
}
}
int c = 0;
while(!st.empty()){
c++;
int si = st.size();
while(si--){
int t = st.front();
//cout << t << " ";
st.pop();
for(int i = 0;i < G[t].size();++i){
int p = G[t][i];
a[p]--;
if(!a[p]) st.push(p);
}
}
// cout << endl;
}
cout << c << endl;
return 0;
}