题意:

给出一棵n个节点的树,这棵树的每条边有一个权值,这个权值只可能是0或1。 在一局游戏开始时,会确定一个节点作为根。接下来从女生开始,双方轮流进行 操作。
当一方操作时,他们需要先选择一个不为根的点,满足该点到其父亲的边权为1; 然后找出这个点到根节点的简单路径,将路径上所有边的权值翻转(即0变成1,1 变成0 )。
当一方无法操作时(即所有边的边权均为0),另一方就获得了胜利。
如果在双方均采用最优策略的情况下,女生会获胜,则输出“Girls win!”,否则输 出“Boys win!”。
为了让游戏更有趣味性,在每局之间可能会有修改边权的操作,而且每局游戏指 定的根节点也可能是不同的。
具体来说,修改边权和进行游戏的操作一共有m个,具体如下:
∙∙“0 x”表示询问对于当前的树,如果以x为根节点开始游戏,哪方会获得胜利。
∙∙“1 x y z ”表示将x和y之间的边的边权修改为z。

分析:

一道在树上的博弈论题

首先,我们先不管是否是最优策略,我们先就愣头青走憨憨走法——每次都走最深的这样一个节点,比如

那么我们按照这个规则,先看左边那条链并先选7号节点

对了,这里其实还有一个小小的性质,每条链末尾的0一定是没用的,因为只有他后面的1才能使它翻转成1,而他是末尾的0

所以知道这个性质以及选完7号节点后,树就变成了这样子

然后就是5号节点

最后是4号节点

你会发现,假如只有这条链的话到这里已经决出胜负了

而且不难发现的是,在这种憨憨决策中,与根节点直接相连的那条边似乎非常的重要

因为假如我们将这条链划分一下肯定是一块全是1的链,一块全是0的链相间分布(显然)

那么我们这种憨憨走法第一步会将最后一块1的链吞掉,然后剩下的链翻转,你也可以理解为规则翻转,也就是说我们下次就要选0的那块了

以此类推,那么如果最后一块是1的话也就是说连接根节点的那条边是1,那么你就会走奇数步,而如果是0的话就会走偶数步

奇数步与偶数步也就对应了游戏的输赢(奇数对应女孩赢,偶数对应男孩赢)

当然,这种憨憨走法男主和女主显然不会这么走

比如

在憨憨走法的前提下,这显然是个男孩必赢的局,那女孩有什么能做的,她可不想输啊!

走5必输,那就走4吧

你会发现,之前的走法会让链的块数减一,而这次却让链的块数加一,但这时如果两人继续“憨憨”的话依然是男孩必赢,因为这次相当于男孩先手,而这次有奇数个块,显然男孩必赢

那么我们不难发现,如果我们即使突然“醒悟”,不憨了,但也难逃输的命运,而已经命中注定赢的那位,只需要一直憨下去就行了,当然他也可以皮一下,但就是输不了就很气

当然一条链是这样,更多的链显然也一定是这样,因为每条链都是“命中注定”,那么我们就可以把一颗树化简成一个根节点连着一些节点

因为每条链的结果只与他与根节点连接的那条边有关

原来一条复杂的树,现在只剩下一个“拖把头”,显然就很好做了,轮流取1就完事了,那么很容易得到,最后“拖把头”里1的个数是奇数就是女孩赢,偶数个就是男孩赢

最后就是这个题目中的修改操作以及换根查询了,修改我直接采用莽着改,的确有超时的风险,不过这题核心是想到这个转化,我觉得做数据的应该是做人的qaq

查询当然也是扫一遍他连着的所有边,具体如何实现,我相信你们都写的出来):

代码:

#include<cstdio> #include<algorithm> #include<vector> using namespace std; const int maxn=4e4+1; struct Node { int pos,val; Node(){} Node(int POS,int VAL){pos=POS,val=VAL;} }; vector<Node> e[maxn]; int main() { int t,n,m,x,y,z,p; scanf("%d",&t); while(t--) { scanf("%d%d",&n,&m); for(int i=1;i<=n;i++)e[i].clear(); for(int i=1;i<n;i++) { scanf("%d%d%d",&x,&y,&z); e[x].push_back(Node(y,z)); e[y].push_back(Node(x,z)); } while(m--) { scanf("%d",&p); if(!p) { scanf("%d",&x); int ans=0; for(int i=0;i<e[x].size();i++) ans+=e[x][i].val; if(ans&1) printf("Girls win!\n"); else printf("Boys win!\n"); } else { scanf("%d%d%d",&x,&y,&z); for(int i=0;i<e[x].size();i++) { if(y==e[x][i].pos) { e[x][i].val=z; break; } } for(int i=0;i<e[y].size();i++) { if(x==e[y][i].pos) { e[y][i].val=z; break; } } } } } return 0; }

说实话我还真不知道咋展示代码[笑哭]

其实实现过程就是把每个节点连接的节点都用vector存一下,然后每次修改的时候就扫一遍,找到你想修改的那个点对应连的边,然后改就完事了

题目分享P的更多相关文章

  1. 2019年腾讯PHP程序员面试题目分享

    有需要学习交流的友人请加入交流群的咱们一起,有问题一起交流,一起进步!前提是你是学技术的.感谢阅读! 点此加入该群​jq.qq.com 1. php 的垃圾回收机制 PHP 可以自动进行内存管理,清除 ...

  2. 20190924-LeetCode解数独题目分享

    解决数独 题目描述 编写一个程序,通过已填充的空格来解决数独问题. 一个数独的解法需遵循如下规则: 数字 1-9 在每一行只能出现一次. 数字 1-9 在每一列只能出现一次. 数字 1-9 在每一个以 ...

  3. 题目分享E 二代目

    题意:一棵点数为n的树,每个节点有点权,要求在树中中找到一个最小的x,使得存在一个点满足max(该点点权,该点相邻的点的点权+1,其他点的点权+2)=x 分析:首先要能把题目转化为上述题意 首先题目让 ...

  4. 题目分享D 二代目

    题意:给定一个T条边的无向图,求S到E恰好经过N条边的最短路径 T≤100 N≤1000000 分析:(据说好像假期学长讲过) 首先很容易想到的是dp[i][j][k]表示从i到j经过k条边的最短路径 ...

  5. 题目分享C 二代目

    题意:一个数列是由 1 1 2 1 2 3 1 2 3 4 1 2 3 4 5 1 2 3 4 5 6.....组成,也就是1-1,1-2,1-3......并且如果遇到多位数也要拆成数字比如1-10 ...

  6. 题目分享X

    题意:一张票有n位数,如果这张票的前一半数字的和等于后一半数字的和(n一定是偶数),就称这张票为快乐票.有些数被擦除了,标记为’?’(’?‘的个数也是偶数),现在Monocarp 和 Bicarp 进 ...

  7. 题目分享V

    题意:现在两个人做游戏,每个人刚开始都是数字1,谁赢了就能乘以k^2,输的乘以k(k可以是任意整数,每次不一定相同)现在给你最终这两个人的得分,让你判断是否有这个可能,有可能的话Yes,否则No. 分 ...

  8. 题目分享T

    题意:蛐蛐国里现在共有n只蚯蚓(n为正整数).每只蚯蚓拥有长度,我们设第i只蚯蚓的长度为a_i(i=1,2,...,n),并保证所有的长度都是非负整数(即:可 能存在长度为0的蚯蚓).每一秒,神刀手会 ...

  9. 题目分享H 二代目

    题意:有m个限制,每个限制l1,r1,l2,r2四个数,限制了一个长度为n的数第l1到r1位要与第l2到r2相同,保证r1-l1=r2-l2,求在限制下一共有多少种数 分析: 暴力的话肯定是从l1-r ...

随机推荐

  1. 手动搭建I/O网络通信框架4:AIO编程模型,聊天室终极改造

    第一章:手动搭建I/O网络通信框架1:Socket和ServerSocket入门实战,实现单聊 第二章:手动搭建I/O网络通信框架2:BIO编程模型实现群聊 第三章:手动搭建I/O网络通信框架3:NI ...

  2. STC15F2K60S2串口通信的应用。

    前言:由于不可抗拒因素,初始的STC12C5A60S2芯片由于无法进行烧录(...因为没带有锁紧座的开发板),暂且使用STC15F2K60S2芯片.. 一 串行通信概述: 串口通信有SPI IIC U ...

  3. 数据结构和算法(Golang实现)(11)常见数据结构-前言

    常见数据结构及算法 数据结构主要用来组织数据,也作为数据的容器,载体. 各种各样的算法,都需要使用一定的数据结构来组织数据. 常见的典型数据结构有: 链表 栈和队列 树 图 上述可以延伸出各种各样的术 ...

  4. Centos 开启网络

    在VMWare上安装了Centos 7,但是发现网络无法连接. # ping www.baidu.com 确认网络无法连接 # ifconfig 查看centos7中的网络配置属性. 启动网络,开启e ...

  5. Redis之事务操作

    1.Redis事务的概念: Redis 事务的本质是一组命令的集合.事务支持一次执行多个命令,一个事务中所有命令都会被序列化.在事务执行过程,会按照顺序串行化执行队列中的命令,其他客户端提交的命令请求 ...

  6. Julia基础语法复数和分数

     1.复数   2.分数

  7. Ubuntu上mysql, 通过python连接报错Can't connect to MySQL server on xxx (10061)

    通过sqlyog连接ubuntu上的mysql报错 试了试python直接连接也报同样的错 那应该就是ubuntu上mysql服务自己的问题了 查看mysql 版本 mysql -V root@clo ...

  8. Mac剪切板中的PNG保存到文件swift

    SwiftGG 教程大全 中文翻译 命令行工具开发教程 Line Programs on macOS Tutorial swift4,较详细 Swift基础中需要注意的点 NSPasteboard M ...

  9. 推荐一个小而美的Python代码格式化工具

    代码可读性是评判代码质量的标准之一,有一个衡量代码质量的标准是 Martin 提出的 “WFT” 定律,即每分钟爆出 “WTF” 的次数.你在读别人代码或者做 Code Review 的时候有没有 “ ...

  10. 异常处理的方式二:throws+异常类型

    package com.yhqtv.demo01Exception; import java.io.File; import java.io.FileInputStream; import java. ...