zoukankan      html  css  js  c++  java
  • HDU 6741 树上删叶子节点博弈

    假设现在有一颗树A

    我们在他非叶子节点上加一个点变成树B 则此时树B必为先手必胜

    假设A为先手必胜 则先手直接把加入的点一同删去

    假设A为先手必败 则先手可以只删加入的点 与后手位置互换 把必败态留给后手

    所以只要有一个非叶子节点连着一个叶子节点(叶子节点父亲的度数>2) 此时的树为先手必胜

    排除掉这种必胜情况 剩下的就是每个叶子节点的父亲度数都为2的情况

    则我们可以计算每个叶子到他第一个度数>2的祖先的长度 如果所有这些长度都为偶数的话 那么是后手必胜

    策略是这样的: 我们定义叶子节点到他第一个度数>2的祖先路上的经过的节点和边为'链'

    假设先手这次拿了集合为S的链上的叶子节点 那么后手也拿集合为S的链上的叶子节点 这样每条链的长度还是偶数 直到有一条链他只剩一个节点直接转换为上面的必胜情况

    如果有一条链是奇数的话 就是先手必胜 因为先手直接把所有链拿成偶数就可以和后手位置互换 把必败态留给后手

    #include<bits/stdc++.h>
    using namespace std;
    int fa[1000005];
    vector<int> G[1000005], yezi;
    int du[1000005], Size[1000005];
    int main() {
            int T;
            scanf("%d", &T) ;
            while (T--) {
                    int n, x;
                    scanf("%d", &n);
                    yezi.clear();
                    for (int i = 1; i <= n; i++) {
                            Size[i] = du[i] = 0;
                            G[i].clear();
                    }
                    for (int i = 2; i <= n; i++) {
                            scanf("%d", &x);
                            fa[i] = x;
                            du[x]++;
                            Size[x]++;
                    }
                    for (int i = 1; i <= n; i++) {
                            if (du[i] == 0) {
                                    yezi.push_back(i);
                            }
                    }
                    bool flag = 0;
                    for (int v : yezi) {
                            int father = fa[v];
                            if (Size[father] >= 2) {
                                    flag = 1;
                                    break;
                            }
                            int cnt = 1;
                            while (Size[fa[v]] == 1) {
                                    cnt++;
                                    v = fa[v];
                            }
                            if (cnt & 1) {
                                    flag = 1;
                                    break;
                            }
                    }
                    if (flag) {
                            printf("Takeru
    ");
                    } else {
                            printf("Meiya
    ");
                    }
            }
            return 0;
    }
  • 相关阅读:
    行内元素知识点
    WPF可视化控件打印
    C#模拟网站用户登录
    不同版本的浏览器代理编码
    WPF弹出对话确认框
    MSDN中HttpWebRequest/HttpWebResponse用法
    C#Http编程
    WPF ICommand 用法
    详述.NET里class和struct的异同
    WPF页面切换及弹窗
  • 原文地址:https://www.cnblogs.com/Aragaki/p/11656291.html
Copyright © 2011-2022 走看看