鏈接: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);
}
}