F 树上博弈

10 篇文章 0 订阅

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

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值