HDU 3197 Game(树删边)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3197

题意:一个森林包含多棵树。游戏者轮流从树上删边,删掉后与树根不相连的就会丢掉。最后不能删的人输。

思路:叶子节点的SG值为0,中间结点的SG值叶子节点的SG值+1的抑或。下面用数学归纳法证明一下。

(1)一个节点和两个节点显然成立。

(2)假设K个节点的树成立。对于K+1个节点。我们首先假设某个节点只有一个子节点,如下图。设根节点为A,中间节点为B。整个树为G,上面的那个子树为G'。那么若在AB边切一刀,则A的SG值为0;若在G'上切一刀,那么其新的SG值可以变为[0,SG[G']-1],所以由结论可得G可以变为[1,SG[G']],然后又可以为0,所以SG[G]=SG[G']+1。

 

那么如果不是只有一个孩子的?有下图。此时,可以看成是若干子游戏,各个孩子的SG+1的抑或。



const i64 mod=1000000007;
const int MAX=1005;

int n;
vector<int> a[MAX],b;

int DFS(int u,int pre)
{
    int i,v,ans=0;
    for(i=0;i<SZ(a[u]);i++)
    {
        v=a[u][i];
        if(v==pre) continue;
        ans^=(DFS(v,u)+1);
    }
    return ans;
}

int main()
{
    while(scanf("%d",&n)!=-1)
    {
        int i,x;
        for(i=0;i<=n;i++) a[i].clear();
        b.clear();
        for(i=0;i<n;i++)
        {
            scanf("%d",&x);
            if(x==-1) b.pb(i);
            else a[i].pb(x),a[x].pb(i);
        }
        int ans=0;
        for(i=0;i<SZ(b);i++) ans^=DFS(b[i],-1);
        if(ans) puts("YES");
        else puts("NO");
    }
    return 0;
}

  

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值