MUV LUV UNLIMITED HDU - 6741【树上博弈】

题意:

一颗树 \(n\) 个节点,两人游戏,每人可选任意个叶子结点删去,最后无法操作的输,问先手必败还是必胜。

分析:

树上博弈。
结论:当存在一个叶子节点,其父亲的儿子个数大于 \(1\) 时,为必胜状态。
证明:假如去掉该点后是一个必胜状态,那么可以把该点和必胜策略的点一起去掉,留给对手必败的状态。如果去掉该点为必败,则只要去掉该点即可。
如果不存在时,可以通过不断删除叶子节点,来达到上述状态,根据删边的数量即可判断即可。

代码:

#include <bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int sz[N],fa[N];
int main()
{
    int T,n;
    scanf("%d",&T);
    while(T--)
    {
        bool f=0;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
        {
            sz[i]=0;
            fa[i]=0;
        }
        int p;
        for(int i=2;i<=n;i++)
        {
            scanf("%d",&p);
            fa[i]=p;
            sz[p]++;
        }
        for(int i=2;i<=n;i++)
        {
            if(sz[i]==0&&sz[fa[i]]>1)
            {
                f=1;
                break;
            }
        }
        if(!f)
        {
            for(int i=2;i<=n;i++)
            {
                if(sz[i]==0)
                {
                    int t=i,cnt=0;
                    while(t!=1&&sz[fa[t]]==1)
                    {
                        t=fa[t];
                        cnt++;
                    }
                    if(cnt%2==0)
                    {
                        f=1;
                        break;
                    }
                }
            }
        }
        if(f) printf("Takeru\n");
        else printf("Meiya\n");
    }
    return 0;
}

参考博客

posted @ 2020-06-01 22:20  xzx9  阅读(231)  评论(0编辑  收藏  举报