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 (博弈论)的主要内容,如果未能解决你的问题,请参考以下文章
2019 China Collegiate K. MUV LUV UNLIMITED(思维,博弈)
Problem A. MUV LUV EXTRA(kmp求最小循环节)
2019 CCPC秦皇岛 J 题 MUV LUV EXTRAKMP 求最小循环节