• AGC017D Game on Tree(树型博弈)


    题目大意:

    给出一棵n个结点的树,以1为根,每次可以切掉除1外的任意一棵子树,最后不能切的话就为负,问是先手必胜还是后手必胜。

    题解:

    首先我们考虑利用SG函数解决这个问题

    如果1结点有多个子节点,那么SG[1]显然就是子节点代表的子树的SG[x]异或和

    所以我们就可以把子树全部拆开

    问题就变成了多个树,每个树的根节点只有一个孩子

    这种情况的SG[1]就等于它的孩子SG[x] + 1

    证明如下

    1、切掉孩子,那么SG[x] = 0,说明SG[1]大于0

    2、切掉其他结点,局面变成[切掉结点的部分]加上[根节点连向孩子的一条边],也就是说当前局面的SG值必定大于[切掉结点的部分]的SG值,而SG值的定义又取最小,所以SG[1] = SG[x] + 1

    然后dfs一遍就可以了

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <vector>
    using namespace std;
    const int maxn = 1e5 +100;
    vector<int> G[maxn];
    int sg[maxn];
    void dfs(int x, int fa){
        sg[x] = 0;
        for(auto to : G[x]){
            if(to == fa) continue;
            dfs(to, x);
            sg[x] ^= (sg[to]+1);
        }
    }
    
    int main()
    {
        int n, x, y;
        cin>>n;
        for(int i = 1; i < n; i++){
            scanf("%d %d", &x, &y);
            G[x].push_back(y);
            G[y].push_back(x);
        }
        dfs(1, 1);
        if(sg[1]) cout<<"Alice";
        else cout<<"Bob";
    }
  • 相关阅读:
    UPC2018组队训练赛第二场
    杭电多校训练第十场
    socks5 代理
    windows pip 报错Unable to find vcvarsall.bat
    emacs笔记
    homestead oci8
    pyenv install
    chrome 设置sock5代理
    laravel 接收post json
    laravel 使用已有数据库自动创建model
  • 原文地址:https://www.cnblogs.com/Saurus/p/7208361.html
Copyright © 2020-2023  润新知