hihocoder1545 : 小Hi和小Ho的对弈游戏(树上博弈&nim博弈)

描述

小Hi和小Ho经常一起结对编程,他们通过各种对弈游戏决定谁担任Driver谁担任Observer。

今天他们的对弈是在一棵有根树 T 上进行的。小Hi和小Ho轮流进行删除操作,其中小Hi先手。

游戏的规则是:每次删除,小Hi或小Ho都可以选择一个非根节点,将以该节点为根的子树从 T 中删除。如果删除之后 T 只剩下一个根节点,则该次操作者胜利。

机智的小Ho认为规则对自己不利,于是他提出了一个补充规则:在小Hi第一次删除之前,小Ho可以选择是否删除根节点。如果他选择删除根节点,则原本的有根树 T 会分裂成一个森林。之后每次删除,小Hi或小Ho都可以选择一个非根节点(不是森林中任何一棵树的根),将以该节点为根的子树删除。如果删除之后森林中只剩下根节点,则该次操作者胜利。

小Hi和小Ho都是睿智的玩家,他们总是会选择最优的方案以获得胜利。

给定初始的有根树T,输出两个布尔值,分别代表小Ho在不删除和删除根节点时,先手的小Hi是否有必胜策略。0代表没有,1代表有。

输入

第一行包含一个整数 Q,代表测试数据的组数。1 ≤ Q ≤ 10

对于每组数据,第一行包含一个正整数 n,代表树T的节点个数。1 ≤ n ≤ 100000

接下来n-1行,每行包含两个整数 xy,代表 xy 的父节点。保证输入是一棵树,节点编号1-n

输出

输出一个长度为2Q的01串,代表答案。

样例输入
2
5
2 5
5 4
2 3
1 2
7
4 7
2 6
1 5
3 4
1 3
1 2
样例输出
1101

思路:green博弈(树删边游戏):规则为每次选择一条边删去,被删去的子树不能再被选,没有可删的一方输掉比赛。

这种题还是要用SG函数来做,此题是最基本的green博弈,我们考虑只有一条边,那么这个边的sg函数就是长度(看成一堆石子);考虑根上有两条链,那么其sg函数就是两个长度的异或(看成两堆石子)...可以推出每个节点的sg函数=所有子节点的sg+1的异或和。

#include<bits/stdc++.h>
#define rep(i,o,l) for(int i=o;i<=l;i++)
using namespace std;
const int maxn=200010;
int Laxt[maxn],Next[maxn],To[maxn],cnt;
int sg[maxn],fcy,ind[maxn],rt;
void add(int u,int v)
{
    Next[++cnt]=Laxt[u]; Laxt[u]=cnt; To[cnt]=v;
}
void dfs(int u,int f)
{
    sg[u]=0;
    for(int i=Laxt[u];i;i=Next[i])
     if(To[i]!=f) dfs(To[i],u);
    sg[f]^=(sg[u]+1);
    if(f==rt) fcy^=sg[u];
}
int main()
{
    int T,N,u,v;
    scanf("%d",&T);
    while(T--){
        scanf("%d",&N); cnt=0; fcy=0;
        rep(i,1,N) ind[i]=0,Laxt[i]=0;
        rep(i,1,N-1) {
            scanf("%d%d",&u,&v);
            add(u,v); ind[v]++;
        }
        rep(i,1,N) if(!ind[i]) rt=i;
        dfs(rt,0);
        putchar(sg[rt]?‘1‘:‘0‘);
        putchar(fcy?‘1‘:‘0‘);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/hua-dong/p/10173141.html

时间: 2024-09-28 21:51:38

hihocoder1545 : 小Hi和小Ho的对弈游戏(树上博弈&nim博弈)的相关文章

C++-hihoCode1545-小Hi和小Ho的对弈游戏[树上Nim]

1 #include <set> 2 #include <map> 3 #include <cmath> 4 #include <queue> 5 #include <vector> 6 #include <cstdio> 7 #include <cstdlib> 8 #include <cstring> 9 #include <iostream> 10 #include <algorithm

1022: [SHOI2008]小约翰的游戏John【Nim博弈,新生必做的水题】

1022: [SHOI2008]小约翰的游戏John Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 2709  Solved: 1726[Submit][Status][Discuss] Description 小约翰经常和他的哥哥玩一个非常有趣的游戏:桌子上有n堆石子,小约翰和他的哥哥轮流取石子,每个人取的时候,可以随意选择一堆石子,在这堆石子中取走任意多的石子,但不能一粒石子也不取,我们规定取到最后一粒石子的人算输.小约翰相当固执,他坚持认为先

HiHo1505:小Hi和小Ho的礼物(Meet-In-The-Middle + 组合数学)

时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 某人有N袋金币,其中第i袋内金币的数量是Ai.现在他决定选出2袋金币送给小Hi,再选2袋金币送给小Ho,同时使得小Hi和小Ho得到的金币总数相等.他想知道一共有多少种不同的选择方法. 具体来说,有多少种下标四元组(i, j, p, q)满足i, j, p, q两两不同,并且i < j, p < q, Ai + Aj = Ap + Aq. 例如对于数组A=[1, 1, 2, 2, 2],一共有12种选法: i j p

hihocoder [Offer收割]编程练习赛14 小Hi和小Ho的礼物

题目1 : 小Hi和小Ho的礼物 时间限制:10000ms 单点时限:1000ms 内存限制:256MB 描述 某人有N袋金币,其中第i袋内金币的数量是Ai.现在他决定选出2袋金币送给小Hi,再选2袋金币送给小Ho,同时使得小Hi和小Ho得到的金币总数相等.他想知道一共有多少种不同的选择方法. 具体来说,有多少种下标四元组(i, j, p, q)满足i, j, p, q两两不同,并且i < j, p < q, Ai + Aj = Ap + Aq. 例如对于数组A=[1, 1, 2, 2, 2]

小Hi和小Ho的礼物

题目:小Hi和小Ho的礼物 注:[i.j.p.q]为下标 个人感觉这道题是有一定难度的.读者可以参考一下[四平方和]的解题思路 分析过程下次补上 代码如下: 1 #include <iostream> 2 #include <unordered_map> 3 using namespace std; 4 5 int main() 6 { 7 int n, a[1000]; 8 long long ans = 0; 9 unordered_map<int, int> cn

微信“小程序”开发小指南

最近两天程序员界最火的应该就是微信“小程序”,抽空试了一下,感觉上手很容易,微信提供的各种组件.API都很全,但是要做的与众不同又性能优良也是不太容易的.本文将首先谈一下我们的小程序运行的架构,然后简单告诉大家几个入门教程的地址. 一.架构 用户户会频繁和微信交互,微信也会频繁与OS交互,当然微信也通过API的方式来获取第三方的数据,并且通过服务组件.开发工具和交互框架来定义小程序的交互样式.展现方式和扩展功能. 二.怎样玩一玩 首先是安装破解版的开发工具,下面的地址写的很详细,地址 接着是教程

假设一对耗子每个月都可以生一对小耗子。小耗子生长3个月后,从第4个月开始也就能够生小耗子。问:假设所有的耗子都不死的话,那么20个月后一共有多少只耗子?

#include <stdio.h>void main(){ int i=0,old=2,first=0,second=0,third=0,sum=0; for(i=0;i<20;i++) { old=old+third; third=second; second=first; first=old; } sum=old+first+second+third; printf("20个月后一共有%d只耗子!\n",sum);} 分析图: 假设一对耗子每个月都可以生一对小耗

由多个电容组成的去耦旁路电路,电容怎么布局摆放,先大后小还是先小后大?

由多个电容组成的去耦旁路电路,电容怎么布局摆放,先大后小还是先小后大? PCB设计规范与指南, 电磁兼容 EMC, 高频高速PCB设计 by xfire 去耦旁路电磁兼容高速电路设计 对于噪声敏感的IC电路,为了达到更好的滤波效果,通常会选择使用多个不同容值的电容并联方式,以实现更宽的滤波频率,如在IC电源输入端用1μF.100nF和10nF并联可以实现更好的滤波效果.那现在问题来了,这几个不同规格的电容在PCB布局时该怎么摆,电源路径是先经大电容然后到小电容再进入IC,还是先经过小电容再经过大

小易邀请你玩一个数字游戏,小易给你一系列的整数。你们俩使用这些整数玩游戏。每次小易会任意说一个数字出来,然后你需要从这一系列数字中选取一部分出来让它们的和等于小易所说的数字。 例如: 如果{2,1,2,7}是你有的一系列数,小易说的数字是11.你可以得到方案2+2+7 = 11.如果顽皮的小易想坑你,他说的数字是6,那么你没有办法拼凑出和为6 现在小易给你n个数,让你找出无法从n个数中选取部分求和

小易邀请你玩一个数字游戏,小易给你一系列的整数.你们俩使用这些整数玩游戏.每次小易会任意说一个数字出来,然后你需要从这一系列数字中选取一部分出来让它们的和等于小易所说的数字. 例如: 如果{2,1,2,7}是你有的一系列数,小易说的数字是11.你可以得到方案2+2+7 = 11.如果顽皮的小易想坑你,他说的数字是6,那么你没有办法拼凑出和为6 现在小易给你n个数,让你找出无法从n个数中选取部分求和的数字中的最小数. 输入描述: 输入第一行为数字个数n (n ≤ 20) 第二行为n个数xi (1