• 2020牛客寒假算法基础集训营4 F树上博弈


    题目描述

    现有一个 n 个点,n-1条边组成的树,其中 1 号点为根节点。
    牛牛和牛妹在树上玩游戏,他们在游戏开始时分别在树上两个不同的节点上。
    在游戏的每一轮,牛牛先走一步,而后牛妹走一步。他们只能走到没有人的空节点上。如果谁移动不了,就输掉了游戏。现在牛牛和牛妹决定随机选择他们分别的起点,于是他们想知道,有多少种游戏开始的方式,使得牛牛存在一种一定获胜的最优策略。
    两种开始方式相同,当且仅当在两种开始方式中牛牛,牛妹的开始位置是分别相同的,否则开始方式就被视作不同的。

    输入描述:

    第一行输入为一个整数 n,代表树的点数。
    第二行n-1个整数$ p_2,p_3,...,p_n $,分别代表2,3,...,n号点的父节点编号。
    $ nleq 10^6,1 leq p_i< i. $

    输出描述:

    一行一个整数,代表答案。

    输入

    3
    1 2

    输出

    2

    说明

    当且仅当牛牛在1号点,牛妹在3号点,或者牛牛在3号点,牛妹在1号点时,牛牛才获胜。

    传送门:

    https://ac.nowcoder.com/acm/contest/3005/F
    
    

    思路:

    首先自己输掉的唯一方法是自己在叶节点,而另一个人在该叶节点的父节点上。

    此时两人的距离D为奇数。

    两人的距离D为奇数时,A先走使得两个人的距离D减小(也就是往根节点走)。

    B也可以采取同样的策略使得两人的距离D减小,最后会到两人的距离为1,该A走。

    此时A只能往叶节点走,B只要跟着A往叶节点走就能获胜。

    偶数的情况同理。

    所以该题只要计算一下每个结点的深度即可。

    代码:

     1 #include<bits/stdc++.h>
     2 
     3 using namespace std;
     4 
     5 const int N = 1e6 + 10;
     6 
     7 struct node
     8 {
     9     int nxt;
    10     int to;
    11 };
    12 
    13 node t[N];
    14 int head[N];
    15 bool vis[N];
    16 int d[N];
    17 
    18 int tot;
    19 void addedges(int u, int v)
    20 {
    21     t[++tot].to = v;
    22     t[tot].nxt = head[u];
    23     head[u] = tot;
    24 }
    25 void dfs(int x)
    26 {
    27     vis[x] = true;
    28 
    29     for(int i = head[x]; i; i = t[i].nxt)
    30     {
    31         int y = t[i].to;
    32         if(!vis[y])
    33         {
    34             d[y] = d[x] + 1;
    35             dfs(y);
    36         }
    37     }
    38 }
    39 int main()
    40 
    41 {
    42     int n;
    43     scanf("%d", &n);
    44     for(int i = 2; i <= n; i++)
    45     {
    46         int x;
    47         scanf("%d", &x);
    48         addedges(x, i);
    49     }
    50     dfs(1);
    51 
    52     long long a = 0;
    53     long long b = 0;
    54     for(int i = 1; i <= n; i++)
    55     {
    56         if(d[i] % 2)
    57             a++;
    58         else
    59             b++;
    60     }
    61     printf("%lld
    ", (a - 1)*a + (b - 1)*b );
    62 }


     
  • 相关阅读:
    微信小程序反编译
    Mac 绑定Gitlab或者GitHub帐号,从新生成公钥
    Vue调试工具vue-devtools安装及使用
    NPM和Yarn添加淘宝镜像
    权限菜单设计
    Axure RP 7.0注册码
    Mac用户抓包软件Charles 4.0 破解 以及 抓取Https链接设置
    [转]c++导出函数dll供c#调用
    ef(EntityFramework)动态传递数据库连接字符串
    [转]sqlserver查询系统表统计表行数和占用空间
  • 原文地址:https://www.cnblogs.com/yyaoling/p/12298257.html
Copyright © 2020-2023  润新知