首页 > 其他分享 >Game on Tree

Game on Tree

时间:2024-05-14 20:54:13浏览次数:19  
标签:cnt int Tree next Game now 节点 dp

原题链接

题解

easy.ver::只能朝一个方向走,还剩奇数个格子时先手获胜

medium.ver: 令 \(u_i\) 为根节点,这样就只能朝子节点的方向走,设 \(dp[now]\) 为当以now为根的树,且now节点已经有一颗棋(其子节点均还没有)时,先手必胜1还是必败0,状态转移方程:\(dp[now]|=(1-dp[next])\)

hard.ver: 考虑沿用medium的想法,并用换根法(因为当前节点只和子节点有关)
假如已知以节点 \(w\) 为根的树的所有节点的胜负情况
那么对于其子节点 \(v\) 而言换根后

  • \(dp[w]=0\) 则 \(dp[v]=1\) 不会变
  • \(dp[w]=1\) 则 \(dp[v]=0\ or\ 1\) 但是如果 \(w\) 只有 \(v\) 一个节点0,那么此时修改 \(dp[w]=0,dp[v]=1\) 不然不变

code

#include<bits/stdc++.h>
using namespace std;
vector<int> G[200005];
int dp[200005]={0};
int cnt[200005]={0};
int ans[200005]={0};
void dfs(int now,int fa)
{
    for(auto next:G[now])
    {
        if(next==fa) continue;
        dfs(next,now);
        dp[now]|=(1-dp[next]);//dp[now] 的意思是当以now为根的树,且now节点已经有一颗棋(其子节点均还没有)时,先手必胜1还是必败0
        cnt[now]+=(1-dp[next]);
    }
}

void alter(int now,int fa)
{
    ans[now]=dp[now];
    int temdp=dp[now],temcnt=cnt[now];
    for(auto next:G[now])
    {
        if(next==fa) continue;
        if(dp[now]==0) cnt[next]++;
        else if(dp[now]==1)
        {
            if(dp[next]==0)
            {
                if(cnt[now]==1)
                {
                    dp[now]=0;
                    dp[next]=1;
                    cnt[next]++;
                }
                cnt[now]--;
            }
        }
        alter(next,now);

        dp[now]=temdp;
        cnt[now]=temcnt;//这个复原工作充分体现了本次换根法的当前节点只与其相邻节点有关
    }
}
int main()
{
    int n,t;
    cin>>n>>t;
    for(int i=1;i<n;i++)
    {
        int x,y;
        cin>>x>>y;
        G[x].push_back(y);
        G[y].push_back(x);
    }


    dfs(1,1);
    alter(1,1);
    while(t--)
    {
        int x;
        cin>>x;
        puts(ans[x]?"Ron":"Hermione");
    }
    return 0;
}

标签:cnt,int,Tree,next,Game,now,节点,dp
From: https://www.cnblogs.com/pure4knowledge/p/18192225

相关文章

  • B. Coin Games
    原题链接题解1.在一次op后,哪些东西发生了变化?哪些东西没变?2.题目要求当一个u都没有的时候先手输,那么我一次op能减几个u?3.通过分类讨论发现一次op总是使u的数量加减一个奇数,所以如果alice要赢,那么起始u的数量必须是奇数code#include<bits/stdc++.h>usingnamespacestd;int......
  • Tree树组件格式化数据、获取所有数据数组
     格式化树数据:functionreplaceNameWithTitle(data){//遍历数据数组returndata.map(item=>{//复制当前对象,以免修改原始数据constnewItem={...item};//将name属性替换为titlenewItem......
  • [题解] Flipping Game
    题目描述有n盏灯,每个灯有开和关两种状态。每按一次灯会变成相反的状态。给定灯初始的开关状态和结束的开关状态,若操作k轮,每轮要按m个不同的灯,问有多少种方法使灯由初始状态变到结束状态。题解需注意每轮要按不同的灯,若无这个条件,暴力计算组合数即可。要操作多轮,且每轮按灯的......
  • 45_jump Game II 跳跃游戏II
    45_jumpGameII跳跃游戏II问题描述链接:https://leetcode.com/problems/jump-game-ii/description/Youaregivena0-indexedarrayofintegersnumsoflengthn.Youareinitiallypositionedatnums[0].Eachelementnums[i]representsthemaximumlengthofafo......
  • Python游戏制作大师,Pygame库的深度探索与实践
    写在前言hello,大家好,我是一点,专注于Python编程,如果你也对感Python感兴趣,欢迎关注交流。希望可以持续更新一些有意思的文章,如果觉得还不错,欢迎点赞关注,有啥想说的,可以留言或者私信交流。如果你想看什么主题的文章,欢迎留言交流,关注公众号【一点sir】,领取编程资料。如果你还不了......
  • 55-jump Game 跳跃游戏
    问题描述Youaregivenanintegerarraynums.Youareinitiallypositionedatthearray'sfirstindex,andeachelementinthearrayrepresentsyourmaximumjumplengthatthatposition.Returntrueifyoucanreachthelastindex,orfalseotherwise解释......
  • CF207C3 Game with Two Trees
    CF207C3GamewithTwoTrees妙到家的树上字符串问题。约定树\(1\):\(t_1\)。树\(2\):\(t_2\)。\(S_{1/2}(i,l)\)为树\(1/2\)上节点\(i\)沿父亲走经过\(l\)​条边所构成的字符串。\(E_{1/2}(u,v)\)为树\(1/2\)上,连接节点\(u,v\)​的边的字符。\(fa_{......
  • 题解:CF1956A Nene's Game
    这道题其实挺有意思,多测里面还套了个多测。思路就是用向量模拟删除过程,具体请看代码里的注释。#include<bits/stdc++.h>usingnamespacestd;intk,q,a[105];voidsolve(){ intn; cin>>n; vector<int>ve; for(inti=1;i<=n;i++)ve.push_back(i);//把每个人放到向量......
  • #Trie#洛谷 6018 [Ynoi2010] Fusion tree
    题目给定一棵树,树上每个节点都有点权,需要实现三种操作,第一种是将与\(x\)相邻的所有节点点权加一,第二种是单点减小点权,第三种是查询与\(x\)相邻的所有节点点权的异或和分析相邻实际上就是父节点和子节点,不妨将其拆开考虑,需要解决单点查询单点修改的问题,考虑维护\(n\)......
  • 一道DP(2024ICPC武汉邀请赛A)-shaking trees
    ShakingTrees题外话这题易哥哥跟我说这题的时候,点明了这题是关于高度\(100\)的\(O(n^3)\)或者\(O(n^4)\)的dp,还有提出切割点的概念使序列化。dp是真的,序列化也是真的。只能说易哥哥我的神。不过其实切割点是根据树形态而变的,之前一直以为是不变的,歪了好久。不知道是我没get到......