F 樹上博弈

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

 

發佈了202 篇原創文章 · 獲贊 20 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章