小白月赛46 D-生活在树上
先将树存起来,既然只能走小于2的距离,那么只用将距离小于2的边存起来,如果大于或者等于2则设为另外一棵树,这样存起来的每一条边都为是1的。然后带着父节点的下标开始从根节点往下遍历,看看两步内能到达多少个节点(有一个子节点就加父节点和自己就+1,然后子节点+2(父节点以及祖父节点),然后再加上父节点除自己以外的子节点数(因为能到达))
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
using namespace std;
#define IOS ios::sync_with_stdio(0), cin.tie(0),cout.tie(0)
#define endl "\n"
typedef long long ll;
const int N=1e6+5;
int res[N];
vector<int> v[N];
vector<int> p;
void dfs(int x,int fa)
{
for (int i=0;i<v[x].size();i++)
{
int j=v[x][i];
res[fa]++;
res[x]++;
if (fa!=0) res[j]++;
res[j]+=v[x].size()-1;
res[j]++;
dfs(j,x);
}
}
int main()
{
int n;
cin>>n;
for (int i=1;i<=n;i++) res[i]=1;
p.push_back(1);
for (int i=2;i<=n;i++)
{
int a,b;
cin>>a>>b;
if (b>2)
{
p.push_back(i);
continue;
}
if (b==2)
{
p.push_back(i);
res[a]++;
res[i]++;
continue;
}
v[a].push_back(i);
}
for (int i=0;i<p.size();i++)dfs(p[i],0);
for (int i=1;i<=n;i++) cout<<res[i]<<endl;
return 0;
}