题目分享P
题意:
给出一棵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的更多相关文章
- 2019年腾讯PHP程序员面试题目分享
有需要学习交流的友人请加入交流群的咱们一起,有问题一起交流,一起进步!前提是你是学技术的.感谢阅读! 点此加入该群jq.qq.com 1. php 的垃圾回收机制 PHP 可以自动进行内存管理,清除 ...
- 20190924-LeetCode解数独题目分享
解决数独 题目描述 编写一个程序,通过已填充的空格来解决数独问题. 一个数独的解法需遵循如下规则: 数字 1-9 在每一行只能出现一次. 数字 1-9 在每一列只能出现一次. 数字 1-9 在每一个以 ...
- 题目分享E 二代目
题意:一棵点数为n的树,每个节点有点权,要求在树中中找到一个最小的x,使得存在一个点满足max(该点点权,该点相邻的点的点权+1,其他点的点权+2)=x 分析:首先要能把题目转化为上述题意 首先题目让 ...
- 题目分享D 二代目
题意:给定一个T条边的无向图,求S到E恰好经过N条边的最短路径 T≤100 N≤1000000 分析:(据说好像假期学长讲过) 首先很容易想到的是dp[i][j][k]表示从i到j经过k条边的最短路径 ...
- 题目分享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 ...
- 题目分享X
题意:一张票有n位数,如果这张票的前一半数字的和等于后一半数字的和(n一定是偶数),就称这张票为快乐票.有些数被擦除了,标记为’?’(’?‘的个数也是偶数),现在Monocarp 和 Bicarp 进 ...
- 题目分享V
题意:现在两个人做游戏,每个人刚开始都是数字1,谁赢了就能乘以k^2,输的乘以k(k可以是任意整数,每次不一定相同)现在给你最终这两个人的得分,让你判断是否有这个可能,有可能的话Yes,否则No. 分 ...
- 题目分享T
题意:蛐蛐国里现在共有n只蚯蚓(n为正整数).每只蚯蚓拥有长度,我们设第i只蚯蚓的长度为a_i(i=1,2,...,n),并保证所有的长度都是非负整数(即:可 能存在长度为0的蚯蚓).每一秒,神刀手会 ...
- 题目分享H 二代目
题意:有m个限制,每个限制l1,r1,l2,r2四个数,限制了一个长度为n的数第l1到r1位要与第l2到r2相同,保证r1-l1=r2-l2,求在限制下一共有多少种数 分析: 暴力的话肯定是从l1-r ...
随机推荐
- AJ学IOS(47)之网易彩票帮助界面UIWebView的运用
AJ分享,必须精品 效果: 制作过程 首先是帮助按钮那个地方的点击. 这里是用点击跳转的用的是 NJSettingArrowItem,前面的设置的,从字典通过模型转过来的. // 分享 NJSetti ...
- 【Java】FlowControl 流程控制
FlowControl 流程控制 什么是流程控制? 控制流程(也称为流程控制)是计算机运算领域的用语,意指在程序运行时,个别的指令(或是陈述.子程序)运行或求值的顺序. 不论是在声明式编程语言或是函数 ...
- ActiveMQ支持的消息协议
ActiveMQ支持哪些协议 ActiveMQ支持多种协议传输和传输方式,允许客户端使用多种协议连接ActiveMQ支持的协议:AUTO,OpenWire,AMQP,Stomp,MQTT等Active ...
- 用Python做一个知乎沙雕问题总结
用Python做一个知乎沙雕问题总结 松鼠爱吃饼干2020-04-01 13:40 前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以 ...
- 简单网络编程如何用python来实现
对于网络编程,通信模式是后台必备技能,先用最基础代码实现,理解一些 API 的含义,在深入学习. 总是有读者问过我关于 Python 后台开发相关,如果想走 Python 后台方向,对于 Python ...
- stand up meeting 12/8/2015
part 组员 今日工作 工作耗时/h 明日计划 工作耗时/h UI 冯晓云 -------------- -- ----------- -- PDF Reader 朱玉影 ...
- Android | 教你如何在安卓上实现二代身份证识别,一键实名认证
@ 目录 前言 场景 开发前准备 android studio 安装 在项目级gradle里添加华为maven仓 在应用级的build.gradle里面加上SDK依赖 在AndroidManifest ...
- Connections in Galaxy War ZOJ - 3261 (并查集)
点权并查集的反向离线操作 题目大意:有n个stars,每一个都一定的“颜值”.然后stars与stars之间可以相连,query c表示再与c相连的stars中,颜值比c高的,stars的标号,如果有 ...
- B. 蚂蚁觅食(二)
B. 蚂蚁觅食(二) 单点时限: 1.0 sec 内存限制: 512 MB 一只饥饿的小蚂蚁外出觅食,幸运的的小蚂蚁发现了好多食物.但是这些食物位于一个N∗M的方格魔法阵的右下角,而小蚂蚁位于方格法阵 ...
- @SessionAttributes 的使用
@SessionAttributes 注解只用作用在 类 上,作用是将指定的 Model 的键值对保存在 session 中.可以让其他请求共用 session 中的键值对. 指定保存的属性名 作用是 ...