HDU 6741 MUV LUV UNLIMITED (博弈论)

Posted suncongbo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 6741 MUV LUV UNLIMITED (博弈论)相关的知识,希望对你有一定的参考价值。

题目链接

http://acm.hdu.edu.cn/showproblem.php?pid=6741

题解

看完题解深刻地意识到自己是个智障。

(1) 如果某个叶子节点的父亲有多于一个儿子,则为必胜态。
证明: 设去掉该叶子后为必败态,则直接删去该点先手必胜;若去掉该叶子后为必胜态,则先手将删去该点之后的必胜策略和这个叶子一同删去,依然是必胜策略。

(2) 若不存在一个叶子结点父亲有多于一个儿子,考虑每个叶子(含)到深度最大的儿子个数多于(1)的祖先(不含)之间的点数。若所有的这些数都是偶数,那么后手必胜,因为后手可以模仿先手直到存在一个叶子结点父亲有多于一个儿子(也就是某个叶子到深度最大的儿子个数多于(1)的祖先只剩(1)的距离了),从而达到必胜态。否则先手必胜,因为先手可以一步转换为后手必胜状态。
时间复杂度(O(n)).

代码

#include<bits/stdc++.h>
#define llong long long
#define mkpr make_pair
#define riterator reverse_iterator
using namespace std;

inline int read()
{
    int x=0,f=1; char ch=getchar();
    for(;!isdigit(ch);ch=getchar()) {if(ch=='-') f = -1;}
    for(; isdigit(ch);ch=getchar()) {x = x*10+ch-'0';}
    return x*f;
}

const int N = 1e6;
int fa[N+3],sonn[N+3];
int n;

int main()
{
    int T = read();
    while(T--)
    {
        n = read();
        for(int i=2; i<=n; i++) fa[i] = read(),sonn[fa[i]]++;
        bool ans = false;
        for(int i=1; i<=n; i++)
        {
            if(sonn[i]==0)
            {
                if(sonn[fa[i]]>1) {ans = true; break;}
                int cnt = 1; for(int u=i; sonn[fa[u]]==1; u=fa[u]) {cnt++;}
                if(cnt&1) {ans = true; break;}
            }
        }
        if(ans==true) puts("Takeru"); else puts("Meiya");
        for(int i=1; i<=n; i++) fa[i] = sonn[i] = 0;
    }
    return 0;
}

以上是关于HDU 6741 MUV LUV UNLIMITED (博弈论)的主要内容,如果未能解决你的问题,请参考以下文章

Gym102361K MUV LUV UNLIMITED

2019 China Collegiate K. MUV LUV UNLIMITED(思维,博弈)

Problem A. MUV LUV EXTRA(kmp求最小循环节)

2019 CCPC秦皇岛 J 题 MUV LUV EXTRAKMP 求最小循环节

2019 CCPC秦皇岛 J 题 MUV LUV EXTRAKMP 求最小循环节

uint8 CIE Luv Mat 的取值范围是多少?