这个题我看反了树。。
优先队列也写反了
逻辑应该是本来优先队列就是大根堆然后我的小于号应该按照d的大小进行重定义(不知道为什么一开始跑出结果来了clion害我)
就是对森林进行拓扑排序然后找拥有最大子树的节点然后删除
#include<iostream>
#include<cstdio>
#include<vector>
#include<queue>
using namespace std;
struct node{
int x,d;
int c;
node(int _x,int _d):x(_x),d(_d){}
bool operator <(const node b)const{
return d<b.d;
}
};
vector<int>v1[1000000+100];
vector<int>st;
int dep[100000+100];
int in[1000000+100];
priority_queue<node>q;
int dfs(int pos){
int now = 1;
for(int i = 0;i<v1[pos].size();++i){
now+=dfs(v1[pos][i]);
}
dep[pos] = now;
return now;
}
int a[100000];
int main(){
int n,k;
scanf("%d%d",&n,&k);
for(int i = 1;i<=n;++i){
int num;
scanf("%d",&num);
if(num==0)st.push_back(i);
else{
v1[num].push_back(i);
in[i]++;
}
}
for(int i = 0;i<st.size();++i){
dfs(st[i]);
}
for(int i = 1;i<=n;++i){
if(in[i]==0){
q.push(node(i,dep[i]));
}
}
int all = 0;
while(!q.empty()){
int cnt = 0;
all++;
for(int i = 0;i<k;++i){
if(!q.empty()){
a[cnt++] = q.top().x;
q.pop();
}
else{
break;
}
}
for(int i = 0;i<cnt;++i){
for(int j =0;j<v1[a[i]].size();++j){
in[v1[a[i]][j]]--;
if(in[v1[a[i]][j]]==0){
q.push(node(v1[a[i]][j],dep[v1[a[i]][j]]));
}
}
}
}
cout<<all<<endl;
}