【HDU - 5963】朋友(博弈,思维,必胜态必败态,找规律)

题干:

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

Input

包含至多5组测试数据。
第一行有一个正整数,表示数据的组数。
接下来每组数据第一行,有二个空格隔开的正整数n,m,分别表示点的个数,操 作个数。保证n,m< 40000。
接下来n-1行,每行三个整数x,y,z,表示树的一条边。保证1<x<n, 1<y< n, 0 <= z <= 1。
接下来m行,每行一个操作,含义如前所述。保证一定只会出现前文中提到的两 种格式。
对于操作0,保证1 <= x <= n ;对于操作1,保证1 <= x <= n, 1 <= y <= n, 0 <= z <= 1,保证树上存在一条边连接x和y。

Output

对于每组数据的每一个询问操作,输出一行“Boys win!”或者“Girls win!”。

Sample Input

2
2 3
1 2 0
0 1
1 2 1 1
0 2
4 11
1 2 1
2 3 1
3 4 0
0 1
0 2
0 3
0 4
1 2 1 0
0 1
0 2
0 3
1 3 4 1
0 3
0 4

Sample Output

Boys win!
Girls win!
Girls win!
Boys win!
Girls win!
Boys win!
Boys win!
Girls win!
Girls win!
Boys win!
Girls win! 

解题报告:

想想他需要不停的换根,数据量又如此庞大,以至于每次换根后,我dfs一遍的时间都没有,所以肯定是个找规律题,肯定不会给你遍历整棵树的机会的。从必胜态必败态的角度考虑,不难发现如果是一条链的情况,规律就是根节点相连的那条边的边权如果是1,那女生胜,反之男生胜。又因为如果是多条链的话,链之间互不影响,所以可以直接统计和根节点相邻的边的边权和,如果是奇数,那就是女生获胜,反之男生获胜。当然如果先一条链然后分成两条链的情况,那其实也问题不大,因为发现可以转化成一条链的情况上面。(其实可以大胆猜想,既然一条链的情况,只和根节点相邻的边的边权有关系,假设这条边是e,那也就是所有 想到达根节点的路径,只要需要经过边e,那就都和路径上的其他边没关系,之和边e相关,所以就这样?)

好吧,还是来一发正解:

正解是,经分析发现无论操作哪个节点,这个节点都会使其所在子树中与根直接相连的那条边翻转。那么再根据游戏的规则以及子树的性质,会发现若你面对当前这条与根相连的边的权值为1时,对方通过子树上任意点来翻转当前边,你都能再次进行翻转。如果你面对权值为0,那么要么你不能进行操作,要么不管你进行什么操作对方都还能进行操作。

AC代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define FF first
#define SS second
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
typedef pair<int,int> PII;
const int MAX = 2e5 + 5;
vector<PII> vv[MAX];
int n,m; 
int main()
{int T;cin>>T;while(T--) {scanf("%d%d",&n,&m);for(int i = 1; i<=n; i++) vv[i].clear(); for(int x,y,z,i = 1; i<=n-1; i++) {scanf("%d%d%d",&x,&y,&z);vv[x].pb(pm(y,z));vv[y].pb(pm(x,z));}for(int i = 1; i<=n; i++) sort(vv[i].begin(),vv[i].end());int op,u,v,z,ans;while(m--) {scanf("%d",&op);if(op == 0) {ans=0; scanf("%d",&u);for(auto x : vv[u]) {if(x.SS == 1) ans++;}if(ans & 1) puts("Girls win!");else puts("Boys win!");}else {scanf("%d%d%d",&u,&v,&z);int pos1 = lower_bound(vv[u].begin(),vv[u].end(),pm(v,-1)) - vv[u].begin();int pos2 = lower_bound(vv[v].begin(),vv[v].end(),pm(u,-1)) - vv[v].begin();vv[u][pos1] = pm(v,z); vv[v][pos2] = pm(u,z);}}} return 0 ;
}

关于实现细节:

发现对于0操作,如果是菊花图的话就炸了。

所以优化一下,发现不需要枚举:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<stack>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define FF first
#define SS second
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
typedef pair<int,int> PII;
const int MAX = 2e5 + 5;
vector<PII> vv[MAX];
int n,m,in[MAX];
int main()
{int T;cin>>T;while(T--) {scanf("%d%d",&n,&m);for(int i = 1; i<=n; i++) vv[i].clear(),in[i]=0; for(int x,y,z,i = 1; i<=n-1; i++) {scanf("%d%d%d",&x,&y,&z);vv[x].pb(pm(y,z));vv[y].pb(pm(x,z));if(z == 1) in[x]++,in[y]++; }for(int i = 1; i<=n; i++) sort(vv[i].begin(),vv[i].end());int op,u,v,z,ans;while(m--) {scanf("%d",&op);if(op == 0) {ans=0; scanf("%d",&u);if(in[u] & 1) puts("Girls win!");else puts("Boys win!");}else {scanf("%d%d%d",&u,&v,&z);int pos1 = lower_bound(vv[u].begin(),vv[u].end(),pm(v,-1)) - vv[u].begin();int pos2 = lower_bound(vv[v].begin(),vv[v].end(),pm(u,-1)) - vv[v].begin();if(vv[u][pos1].SS==0 && z == 1) {vv[u][pos1] = pm(v,z); vv[v][pos2] = pm(u,z);in[u]++,in[v]++;}else if(vv[u][pos1].SS==1 && z == 0) {vv[u][pos1] = pm(v,z); vv[v][pos2] = pm(u,z);in[u]--,in[v]--;}                }}} return 0 ;
}

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/439721.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一步步编写操作系统 39 二级页表1

前面讲述了页表的原理&#xff0c;并以一级页表做为原型讲述了地址转换过程。既然有了一级页表&#xff0c;为什么还要搞个二级页表呢&#xff1f;理由如下&#xff1a; 一级页表中最多可容纳1M&#xff08;1048576&#xff09;个页表项&#xff0c;每个页表项是4字节&#xf…

PointNet++详解与代码

在之前的一篇文章《PointNet&#xff1a;3D点集分类与分割深度学习模型》中分析了PointNet网络是如何进行3D点云数据分类与分割的。但是PointNet存在的一个缺点是无法获得局部特征&#xff0c;这使得它很难对复杂场景进行分析。在PointNet中&#xff0c;作者通过两个主要的方法…

一步步编写操作系统 40 内存分页下用户程序与操作系统的关系

分页的第一步要准备好一个页表&#xff0c;我们的页表是什么样子呢&#xff1f;现在我们要设计一个页表啦。 设计页表其实就是设计内存布局&#xff0c;不过在规划内存布局之前&#xff0c;我们需要了解用户进程与操作系统之间的关系。 前面讲保护模式时&#xff0c;我们知道…

【HDU - 4055】Number String(dp,思维)

题干&#xff1a; The signature of a permutation is a string that is computed as follows: for each pair of consecutive elements of the permutation, write down the letter I (increasing) if the second element is greater than the first one, otherwise write do…

一步步编写操作系统 41 快表tlb 简介

分页机制虽然很灵活&#xff0c;但您也看到了&#xff0c;为了实现虚拟地址到物理地址的映射&#xff0c;过程还是有些麻烦的。先要从CR3寄存器中获取页目录表物理地址&#xff0c;然后用虚拟地址的高10位乘以4的积做为在页目录表中的偏移量去寻址目录项pde&#xff0c;从pde中…

【CodeForces - 731C】Socks(并查集,思维)

题干&#xff1a; Arseniy is already grown-up and independent. His mother decided to leave him alone for m days and left on a vacation. She have prepared a lot of food, left some money and washed all Arseniys clothes. Ten minutes before her leave she real…

50个最有用的Matplotlib数据分析与可视化图

本文介绍了数据分析与可视化中最有用的50个数据分析图&#xff0c;共分为7大类&#xff1a;Correlation、Deviation、RankIng、Distribution、Composition、Change、Groups 原文链接&#xff1a;https://www.machinelearningplus.com/plots/top-50-matplotlib-visualizations-t…

一步步编写操作系统 42 用c语言编写内核

在这之前&#xff0c;我们一直用汇编语言直接与机器对话&#xff0c;如果大家不知道这个世界上有高级语言的话&#xff0c;我想大家也不会觉得写汇编代码的过程很辛苦&#xff0c;哈哈&#xff0c;幸福确实是比较出来的。相对于汇编语言&#xff0c;用c 语言写内核是非常爽的事…

【CodeForces - 722C】Destroying Array(并查集,时光倒流)

题干&#xff1a; 给定一个有n个数的序列a1,a2, ..., an 你每次可以将序列中一个数删去&#xff0c;剩下的数会被分割为一段一段连续的数列 给定一个删除数的顺序&#xff0c;问在每次删除之后&#xff0c;剩下的连续的数列中&#xff0c;数列和的最大值为多少 Input 第…

视觉SLAM十四讲(1):预备知识

最近在学习高翔博士的《视觉SLAM十四讲》&#xff08;第二版&#xff09;&#xff0c;算是初学本书&#xff0c;配套资源还算蛮丰富的&#xff0c;有代码&#xff08;第一版和第二版都有&#xff09;&#xff0c;B站上也有高翔博士对第一版录制的讲解视频&#xff0c;真的是很贴…

一步步编写操作系统 43 汇编语言和c语言的理解

也许有的同学喜欢用汇编语言来实现操作系统&#xff0c;觉得用汇编来写程序似乎更简单直接&#xff0c;可控性比较强&#xff0c;有种“一切尽在掌握”的赶脚。而用c语言实现操作系统这件事&#xff0c;虽然轻松很多&#xff0c;但似乎隐约感觉到有些慌张。因为虽然c语言相对来…

视觉SLAM十四讲(2):初识SLAM

这一讲主要介绍视觉SLAM的结构&#xff0c;并完成第一个SLAM程序&#xff1a;HelloSLAM。 目录 2.1 小萝卜的例子 单目相机 双目相机 深度相机 2.2 经典视觉SLAM框架 2.3 SLAM问题的数学表述 2.4 编程实践 Hello SLAM 使用cmake 使用库 【高翔】视觉SLAM十四讲2.1 小…

【CodeForces - 467C】George and Job(dp,思维)

题干&#xff1a; The new ITone 6 has been released recently and George got really keen to buy it. Unfortunately, he didnt have enough money, so George was going to work as a programmer. Now he faced the following problem at the work. Given a sequence of …

一步步编写操作系统 44 用c语言编写内核1

先来个简单的&#xff0c;欢迎我们神秘嘉宾——main.c。这是我们第一个c语言代码。 1 int main(void) { 2 while(1); 3 return 0; 4 }它没法再简单啦&#xff0c;简单的程序似乎能帮助咱们更容易的理解所学的知识&#xff0c;哈哈&#xff0c;我说的是似乎&#xff0c;其实&…

从零实现一个3D目标检测算法(1):3D目标检测概述

本文是根据github上的开源项目&#xff1a;https://github.com/open-mmlab/OpenPCDet整理而来&#xff0c;在此表示感谢&#xff0c;强烈推荐大家去关注。使用的预训练模型也为此项目中提供的模型&#xff0c;不过此项目已更新为v0.2版&#xff0c;与本文中代码略有不同。 本文…

【Codeforces - 900C】Remove Extra One(思维,STLset,tricks)

题干&#xff1a; You are given a permutation p of length n. Remove one element from permutation to make the number of records the maximum possible. We remind that in a sequence of numbers a1, a2, ..., ak the element ai is a record if for every integer…

一步步编写操作系统 45 用c语言编写内核2

在linux下用于链接的程序是ld&#xff0c;链接有一个好处&#xff0c;可以指定最终生成的可执行文件的起始虚拟地址。它是用-Ttext参数来指定的&#xff0c;所以咱们可以执行以下命令完成链接&#xff1a; ld kernel/main.o -Ttext 0xc0001500 -e main -o kernel/kernel.bin …

【Codeforces - 977F】Consecutive Subsequence(STLmap,输出路径,dp)

题干&#xff1a; You are given an integer array of length nn. You have to choose some subsequence of this array of maximum length such that this subsequence forms a increasing sequence of consecutive integers. In other words the required sequence should …

使用OpenCV库快速求解相机内参

本文主要介绍如何使用OpenCV库函数求解相机内参。具体可查阅官网&#xff1a;https://docs.opencv.org/master/dc/dbb/tutorial_py_calibration.html。 关于相机内参的求解还有很多其它的工具&#xff0c;如使用MATLAB求解会更方便&#xff0c;直接调用MATLAB中的APP即可。 1.背…

一步步编写操作系统 46 用c语言编写内核3

再把上节代码贴出来&#xff0c; 1 //int main(void) { 2 int _start(void) { 3 while(1); 4 return 0; 5 }有没有同学想过&#xff0c;这里写一个_start函数&#xff0c;让其调用main函数如何&#xff1f;其实这是可以的&#xff0c;main函数并不是第一个函数&#xff0c;它实…