链接:https://ac.nowcoder.com/acm/contest/3005/F
现有一个 n 个点,n-1条边组成的树,其中 1 号点为根节点。
牛牛和牛妹在树上玩游戏,他们在游戏开始时分别在树上两个不同的节点上。
在游戏的每一轮,牛牛先走一步,而后牛妹走一步。他们只能走到没有人的空节点上。如果谁移动不了,就输掉了游戏。现在牛牛和牛妹决定随机选择他们分别的起点,于是他们想知道,有多少种游戏开始的方式,使得牛牛存在一种一定获胜的最优策略。
两种开始方式相同,当且仅当在两种开始方式中牛牛,牛妹的开始位置是分别相同的,否则开始方式就被视作不同的。
输入描述:
第一行输入为一个整数 n,代表树的点数。
第二行n-1个整数p_2,p_3,\ldots,p_{n}p2,p3,…,pn,分别代表2,3,...,n号点的父节点编号。
输出描述:
一行一个整数,代表答案。
示例1
输入
复制
3 1 2
输出
复制
2
说明
当且仅当牛牛在1号点,牛妹在3号点,或者牛牛在3号点,牛妹在1号点时,牛牛才获胜。
示例2
输入
复制
2 1
输出
复制
0
说明
由于无论如何牛牛都无路可走,因此必然牛妹获胜。
示例3
输入
复制
30 1 1 2 1 2 1 3 2 3 4 2 3 1 2 3 4 2 4 5 6 3 4 12 12 12 13 13 13 13
输出
复制
428
说明
QwQ
备注:
n \le 10^6n≤106 1\le p_i < i1≤pi<i
#include<bits/stdc++.h>
using namespace std;
long long n,k,ans,s1,s2,t,max1=1;
long long a[1000001],b[1000001];
map<long long,long long>m;
int main()
{
cin>>n;
a[1]=1;
m[1]++;
for(int i=2;i<=n;i++)
{
scanf("%lld",&t);
a[i]=a[t]+1;
max1=max(max1,a[i]);
m[a[i]]++;
}
if(n==2)
cout<<0;
else
{
s1=0;
s2=0;
for(int i=1;i<=max1;i++)
{
if(i%2==1)
s1+=m[i];
else
s2+=m[i];
}
cout<<(s1-1)*s1+s2*(s2-1);
}
}