当前位置: 首页 > news >正文

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君当然知道怎么做啦!但是他想考考你。

思路:

树上博弈,一般都是思维模拟找规律,但今天做这题因为好久没做只写出一个超时的版本...分析的时候自己完全没有去侧重根x去分析,写了一张纸不同情形的子树去分析,最终发现一棵子树中不管怎么去操作最终操作次数的奇偶性是确定的,但是不足以解决这题= =

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

所以对于当前根为x,只需统计与x相连的所有边1的个数,为奇先手必胜,为偶先手必输。

代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 4e4+5;
const int bas = 4e4+1;
unordered_map<int, int> has;
vector<int> g[maxn];
int t, n, m, ans[maxn];
int main()
{
	//freopen("in.txt", "r", stdin);
	for(scanf("%d", &t); t--;)
	{
		scanf("%d %d", &n, &m);
		for(int i = 1; i <= n; ++i) g[i].clear();
		for(int i = 1; i < n; ++i)
		{
			int u, v, w;
			scanf("%d %d %d", &u, &v, &w);
			g[u].push_back(v);
			g[v].push_back(u);
			if(u > v) swap(u, v);
			has[u*bas+v] = w;
		}
		for(int i = 1; i <= n; ++i)
		{
			int tmp = 0;
			for(int j = 0; j < g[i].size(); ++j)
			{
				int v = g[i][j], u = i;
				if(u > v) swap(u, v);
				tmp += has[u*bas+v];
			}
			ans[i] = tmp&1;
		}
		for(int i = 1; i <= m; ++i)
		{
			int key, x, y, z;
			scanf("%d", &key);
			if(key)
			{
				scanf("%d %d %d", &x, &y, &z);
				if(x > y) swap(x, y);
				if(z != has[x*bas+y])
				{
					ans[x] ^= 1;
					ans[y] ^= 1;
					has[x*bas+y] = z;
				}
			}
			else
			{
				scanf("%d", &x);
				if(ans[x]&1) puts("Girls win!");
				else puts("Boys win!");
			}
		}
	}
	return 0;
}


继续加油~

相关文章:

  • HDU 6005 Pandaland(无向图最小环)
  • Cura源码在Ubuntu15.04上编译脚本(成功)
  • SPOJ - CHICAGO 106 miles to Chicago(乘积最短路)
  • HTML5之FileReader的使用
  • LeetCode 202 Happy Number(floyd判圈算法(龟兔赛跑算法))
  • css3 中text-align:justify
  • HDU-1503 Advanced Fruits(LCS)
  • LightOJ-1253 Misere Nim(Nim求解不正常的博弈)
  • python发送电子邮件模块smtplib
  • uva-1349 Optimal Bus Route Design(最小费用最大流)
  • 一个简单的通用验证类的实现
  • ZOJ-3987 Numbers 2017CCPC秦皇岛站G题 (二进制乱搞、贪心)
  • iOS开发-类簇(Class Cluster)
  • HDU-1350 Taxi Cab Scheme(最小路径覆盖)
  • codeforces-884D Boxes And Balls(思维、三叉哈夫曼树)
  • 10个最佳ES6特性 ES7与ES8的特性
  • GraphQL学习过程应该是这样的
  • HTTP中GET与POST的区别 99%的错误认识
  • js ES6 求数组的交集,并集,还有差集
  • Laravel Mix运行时关于es2015报错解决方案
  • Making An Indicator With Pure CSS
  • Mysql优化
  • Vue全家桶实现一个Web App
  • 安卓应用性能调试和优化经验分享
  • 案例分享〡三拾众筹持续交付开发流程支撑创新业务
  • 从地狱到天堂,Node 回调向 async/await 转变
  • 老板让我十分钟上手nx-admin
  • 模型微调
  • 配置 PM2 实现代码自动发布
  • 前端相关框架总和
  • 新手搭建网站的主要流程
  • 一个JAVA程序员成长之路分享
  • 再谈express与koa的对比
  • 怎么把视频里的音乐提取出来
  • PostgreSQL之连接数修改
  • ​批处理文件中的errorlevel用法
  • !$boo在php中什么意思,php前戏
  • #【QT 5 调试软件后,发布相关:软件生成exe文件 + 文件打包】
  • #经典论文 异质山坡的物理模型 2 有效导水率
  • $redis-setphp_redis Set命令,php操作Redis Set函数介绍
  • (Note)C++中的继承方式
  • (SpringBoot)第七章:SpringBoot日志文件
  • (二)基于wpr_simulation 的Ros机器人运动控制,gazebo仿真
  • (转) ns2/nam与nam实现相关的文件
  • (转)Scala的“=”符号简介
  • .NET Core MongoDB数据仓储和工作单元模式封装
  • .NET Framework 服务实现监控可观测性最佳实践
  • .Net Remoting(分离服务程序实现) - Part.3
  • .NET 材料检测系统崩溃分析
  • .NET 发展历程
  • .Net各种迷惑命名解释
  • .sys文件乱码_python vscode输出乱码
  • @test注解_Spring 自定义注解你了解过吗?
  • [ vulhub漏洞复现篇 ] Grafana任意文件读取漏洞CVE-2021-43798
  • [ 云计算 | AWS ] 对比分析:Amazon SNS 与 SQS 消息服务的异同与选择