题目大意:一个树,两个操作,
1.传染:(一个节点下至少有一个被感染的子节点,则此节点健康的一个子节点会被传染一个);
2.传播:(一个健康的节点被传播)
求所有节点被传播的最小时间。
思路:
按照子节点的大小进行第一场传播,对每个节点来说子节点全感染的时间:子节点数-子节点被传染的次序+1;
第一场传播之后,建立降序优先队列:节点的子节点数-传播次数+1;
ans(时间),若是ans>=队列的第一个值break;否则,ans+1,队列第一个值-1;
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=3e5+10;
int a[N];
int main()
{
int n;
cin>>n;
while(n--)
{
int t;
cin>>t;
int ans=1;
for(int i=2;i<=t;i++)
{
int x;
cin>>x;
a[x]++;
}
sort(a+1,a+t+1,greater<int>());
priority_queue<int,vector<int>,less<int> >heap;
for(int i=1;i<=t;i++)
{
if(a[i])
{
ans++;
heap.push(a[i]+i-1);
a[i]=0;
}
else
break;
}
while(ans<heap.top())
{
int x=heap.top()-1;
heap.pop();
heap.push(x);
ans++;
}
printf("%d\n",ans);
}
return 0;
}