2019 China Collegiate Programming Contest Qinhuangdao K. MUV LUV UNLIMITED

MUV LUV UNLIMITED

Link

题目大意:给出一棵树,两人轮流任取(至少取一)当前树上的叶子,最先不能操作的人输。

首先考虑一个情况,若一个叶子节点 x x x 有兄弟,则先手必胜。因为如果我取了 x x x 以后的树是先手必败态,那么我取这个叶子就必胜了。如果不是,则取完 x x x 之后到达了先手必胜态,那么此时第二个人取一次之后肯定又变为了先手必败态,假设第二个人取的点集为 s s s ,也就是说取了 { x } ∪ S \{x\}∪S {x}S 之后变为了先手必败态,而我们现在得知 x x x 有兄弟,也就是说取完 x x x 之后不会产生新的叶子节点,所以第一个人也可以选择再取 s s s ,也就是说先手可以直接取完 { x } ∪ S \{x\}∪S {x}S ,这样先手又赢了。所以只要叶子节点有兄弟,就先手必胜。

那么现在我们考虑每个叶子节点都没兄弟的情况 ,那么假如全局没有分叉点,那么显然这颗树就是一条链,则如果是点数为偶数的话先手必败。那么假如我们现在定义分叉链的长度为一个叶子向上遇到的第一个分叉点(最近的 儿子数量大于 1 1 1 的 祖先)的距离。那么如果所有分叉链长度都为偶数的话,后手只要每次都跟着先手做一样的操作,那么每次先手遇到的都是全偶链,所以后面只要是有奇链,一定是后手遇见的,所以,如下这种情况, 一定后手遇见的(图中三角形代表的子树非空):
在这里插入图片描述
那么我们一开始就分析过,一个叶子节点如果有兄弟,那么其是必胜态,然而一定是后手先遇见这个状态,所以此时后手必胜。反之只要存在一个奇数链,先手只要第一次把奇数链都取一个,就能将将全偶状态转移给了后手,这样后手就变成了必败态。

所以,综上所述,只要某个叶子节点有兄弟则先手必胜,否则若存在奇数长度的分叉链先手必胜,不存在则后手必胜。

#include <bits/stdc++.h>

using namespace std;

const int N = 1e6 + 10;

int out[N], fa[N];

int main() {
#ifndef ONLINE_JUDGE
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
#endif
    int T;
    scanf("%d", &T);
    while(T--) {
        int n; scanf("%d", &n);
        for (int i = 1; i <= n; ++i) {
            fa[i] = out[i] = 0;
        }
        for (int i = 2; i <= n; ++i) {
            int x; scanf("%d", &x);
            fa[i] = x;
            out[x]++;
        }
        bool fir = false;
        for (int i = 1; i <= n; ++i) {
            if (!out[i]) {
                if (out[fa[i]] > 1) {
                    fir = true;
                    break;
                }
                int cnt = 0;
                int u = fa[i];
                while(1) {
                    cnt++;
                    if (out[u] > 1 || u == 0) break;
                    u = fa[u];
                }
                if (cnt & 1) {
                    fir = true;
                    break;
                }
            }
        }
        if (fir) {
            puts("Takeru");
        }
        else {
            puts("Meiya");
        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值