AT2667 [AGC017D] Game on Tree

有一棵 \(N\) 个节点的树,节点标号为 \(1,2,⋯,N\),边用 \((x_i,y_i)\)表示。 Alice 和 Bob 在这棵树上玩一个游戏,Alice先手,两人轮流操作:

选择一条树上存在的边,把它断开使树变成两个连通块。然后把不包含 \(1\) 号点的联通块删除

当一个玩家不能操作时输,你需要算出:假如两人都按最优策略操作,谁将获胜。

\[sg(u)=\bigoplus_{v\in son(u)}sg(v)+1 \]

证明还不会,占个坑,好像还有个叫克朗原理的东西,有空学学

Code

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
const int N = 2e5;
using namespace std;
int n,edge[N * 2 + 5],nxt[N * 2 + 5],head[N + 5],edge_cnt,sg[N + 5];
void add_edge(int u,int v)
{
    edge[++edge_cnt] = v;
    nxt[edge_cnt] = head[u];
    head[u] = edge_cnt;
}
void dfs(int u,int fa)
{
    for (int i = head[u];i;i = nxt[i])
    {
        int v = edge[i];
        if (v == fa)
            continue;
        dfs(v,u);
        sg[u] ^= sg[v] + 1;
    }
}
int main()
{
    scanf("%d",&n);
    int u,v;
    for (int i = 1;i < n;i++)
    {
        scanf("%d%d",&u,&v);
        add_edge(u,v);
        add_edge(v,u);
    }
    dfs(1,0);
    if (sg[1])
        cout<<"Alice"<<endl;
    else
        cout<<"Bob"<<endl;
    return 0;
}
posted @ 2020-09-09 09:23  eee_hoho  阅读(209)  评论(0编辑  收藏  举报