题意:第一行输入n,表示有n个人,编号为1~n,其中1是老板,他没有上司。
第二行输入n-1个数字,其中a[i]表示a[i]是i的上司。
每次分配任务时,都从老板(1号)开始将任务推给自己的下级(当有多个下级时选择编号较小的)直到分配到最底层的员工,由最底层的员工开始执行。每次执行这个任务的员工可以获得1元,他的上司获得2元,上司的上司3元……执行完任务后该员工就会离开这个公司,最后整个公司只剩下老板,老板执行了他的第一个任务后也离开了。问最后每个人赚的钱分别是多少。
思路:上一级每次都比下一级多赚一元,如果能够知道到下一级自己执行任务为止下一级总共赚了多少次钱,就可以知道上一级比下一级多赚了多少钱。上一级赚的钱一定是下一级赚的钱+下一级赚钱的次数,即上级赚的钱=∑(下级赚的钱+下级自己加上下级的下级有多少个)
#include <iostream>
#include <vector>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <stack>
using namespace std;
typedef long long ll;
stack<ll> st;
ll n;
ll in[200005];
ll fa[200005];
ll ans[200005];
ll side[200005];
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(0);cout.tie(0);
memset(ans,0,sizeof(ans));
memset(in,0,sizeof(in));
while(!st.empty()) st.pop();
cin >> n;
for(int i=2; i<=n; i++)
{
ll a;
cin >> a;
fa[i]=a;
in[a]++;
}
fa[1]=0;
for(int i=1;i<=n;i++)
if(in[i]==0)
st.push(i);
while(!st.empty())
{
ll x=st.top();//x做任务
st.pop();
ll f=fa[x];//f是x的上一级
side[x]++;//表示x有多少个下级(包括x自己)
ans[x]++;
side[f]+=side[x];
ans[f]+=side[x]+ans[x];
in[f]--;
if(in[f]==0) st.push(f);
}
for(int i=1;i<=n;i++)
cout<<ans[i]<<" ";
return 0;
}