题意是:

一群男生和一群女生玩游戏:给出一棵 n 个节点的树,这棵树的每条边有一个权值 0 或 1。 在一局游戏开始时,确定一个节点作为根。从女生开始,双方轮流进行操作。

当一方操作时,要先选择一个不为根且到其父亲的边权为 1 的点,然后找出这个点到根节点的简单路径,将路径上所有边的权值翻转(即 0 变成 1,1 变成 0 )。

当一方无法操作时(即所有边的边权均为 0),另一方就获得了胜利。双方均采用最优策略,若女生获胜,则输出 “Girls win!”,否则输出“Boys win!”。

每局之间可能会有修改边权的操作,且每局游戏指定的根节点也可能是不同的。

开始时以为会很麻烦,借鉴了别人的博客,才想到修改边权只能每次修改一条边的,有了一些思路:

首先要明确结果只有两种,当操作数为奇数时女生获胜,当操作数为偶数时男生获胜。

一、 这种情况下需要经过两次操作才能将所有权值置 0 ;二、 这种情况下需要经过一次或三次操作才能将所有权值置 0 ;

三、这种情况下需要经过两次或四次操作才能将所有权值置 0 ;四、 这种情况下需要经过三次或五次操作才能将所有权值置 0。

上述四种情况的结论是只要进行操作就一定会出现的,不一定要特别采用最优策略,也就是说情况出现后先手与后手的输赢已经确定,双方只要按规则操作即使想可以改变结果也

无法做到,其实应该还有第五种情况,就是都为 0 的情况,这种情况下需要零次操作才能将所有权值置 0。

发现,当与根结点相连的边权和为偶数时需要且一定经过偶数次操作才能将所有权值置 0,当与根结点相连的边权和为奇数时需要且一定经过奇数次操作才能将所有权值置 0。

开始时打算用 40000*40000 的 bool 数组去存,但还是超内存了……

错误代码:

 #include <bits/stdc++.h>
using namespace std;
bool p[][];
int main()
{
int t,n,m,x,y,z;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
memset(p,,sizeof(p));
for(int i = ; i < n; ++i)
{
scanf("%d%d%d",&x,&y,&z);
p[x][y] = z;
p[y][x] = z;
}
for(int i = ; i < m; ++i)
{
scanf("%d",&z);
if(z)
{
scanf("%d%d%d",&x,&y,&z);
p[x][y] = z;
p[y][x] = z;
}
else
{
scanf("%d",&z);
x = ;
for(int i = ; i < ; ++i)
if(p[z][i]) ++x;
if(x&) puts("Girls win!");
else puts("Boys win!");
}
}
}
return ;
}

改成 vector 数组才过了

代码如下:

 #include <bits/stdc++.h>
using namespace std;
vector<int> p[];
int num[];
int main()
{
int t,x,y,z,n,m;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
memset(num,,sizeof(num));
memset(p,,sizeof(p));
for(int i = ; i < n; ++i)
{
scanf("%d%d%d",&x,&y,&z);
if(z)
{
++num[x];
++num[y];
p[x].push_back(y);
p[y].push_back(x);
}
}
for(int i = ; i < m; ++i)
{
scanf("%d",&z);
if(z)
{
scanf("%d%d%d",&x,&y,&z);
vector<int>::iterator it1 = find(p[x].begin(),p[x].end(),y);
vector<int>::iterator it2 = find(p[y].begin(),p[y].end(),x);
if(it1!=p[x].end() && z==)
{
--num[x];
--num[y];
p[x].erase(it1);
p[y].erase(it2);
}
if(it1==p[x].end() && z==)
{
++num[x];
++num[y];
p[x].push_back(y);
p[y].push_back(x);
}
}
else
{
scanf("%d",&z);
if(num[z]&) puts("Girls win!");
else puts("Boys win!");
}
}
}
return ;
}

感谢这篇博客的作者:

https://blog.csdn.net/song_4/article/details/53063309

HDU 5963(游戏 博弈+规律)的更多相关文章

  1. 最简单的博弈论——HDU - 5963 朋友 (博弈)

    OK,好的先看一下题意: B君在围观一群男生和一群女生玩游戏,具体来说游戏是这样的: 给出一棵n个节点的树,这棵树的每条边有一个权值,这个权值只可能是0或1. 在一局游戏开始时,会确定一个节点作为根. ...

  2. HDU 5963 朋友 (找规律,思维)

    HDU 5963 朋友 题目大意 B君在围观一群男生和一群女生玩游戏,具体来说游戏是这样的: 给出一棵n个节点的树,这棵树的每条边有一个权值,这个权值只可能是0或1. 在一局游戏开始时,会确定一个节点 ...

  3. HDU 4315 阶梯博弈变形

    n个棋子,其中第k个是红色的,每个棋子只能往上爬,而且不能越过.重叠其他棋子,谁将红色棋子移到顶部谁赢. 由于只能往上爬,所以很像阶梯博弈.这题有2个限制,棋子不能重叠,有红棋存在 首先不考虑红色棋, ...

  4. HDU 1564 简单博弈 水

    n*n棋盘,初始左上角有一个石头,每次放只能在相邻的四个位置之一,不能操作者输. 如果以初始石头编号为1作为后手,那么对于每次先手胜的情况其最后一步的四周的编号必定是奇数,且此时编号为偶数,而对于一个 ...

  5. HDU 5963 朋友(找规律博弈)

    http://acm.hdu.edu.cn/showproblem.php?pid=5963 题意: 思路: 我们可以先只考虑单链,自己试几种案例就可以发现规律,只有与根相连的边为1时,只需要奇数次操 ...

  6. HDU 5963 博弈

    http://acm.hdu.edu.cn/showproblem.php?pid=5963 题目大意:中文题 思路:看ICPC camp好了,简单易懂:https://async.icpc-camp ...

  7. vijos 1004 伊甸园日历游戏 博弈+打表找规律

    描述 Adam和Eve玩一个游戏,他们先从1900.1.1到2001.11.4这个日期之间随意抽取一个日期出来.然后他们轮流对这个日期进行操作: 1 : 把日期的天数加1,例如1900.1.1变到19 ...

  8. 【博弈】HDU - 5963 朋友

    题目 B君在围观一群男生和一群女生玩游戏,具体来说游戏是这样的: 给出一棵n个节点的树,这棵树的每条边有一个权值,这个权值只可能是0或1. 在一局游戏开始时,会确定一个节点作为根.接下来从女生开始,双 ...

  9. HDU 1527 (Wythoff 博弈) 取石子游戏

    对于Wythoff博弈中的两个数列,An和Bn有这样的关系: An + n = Bn, An = floor(φ * n) 所以我们可以根据a b的差值来计算一个新的a出来看看这两个值是否相等. 想等 ...

随机推荐

  1. php操作Memcache的一个类库

    ###php操作Memcache的一个类库 代码如下: <?php /** * Created by PhpStorm. * User: alisleepy * Date: 2019-03-14 ...

  2. 我的第一个python web开发框架(26)——定制ORM(二)

    弄完底层数据库操作模块后,接下来要做的是ORM的正式设计.在开始之前,我们需要思考一下怎么来设计一个ORM呢?这个类它能帮助我们处理什么样的问题?需要有哪些功能模块?怎么做到针对不同的数据库与表单进行 ...

  3. ORACLESQL语句的优化

    ORACLESQL语句的优化: 选择最有效率的表名顺序:应该选择记录条数最少的表作为基表! 因为Oracle解析器的处理顺序是从右至左的.当ORACLE处理多个表时, 会运用排序及合并的方式连接它们. ...

  4. jenkins之Job建立-运行 git 脚本

    新建一个自由风格的项目,运行git脚本 1.点击菜单栏中的“新任务” 2.进入该页面后输入一个项目名称,然后选择“构建一个自由风格的软件项目”,滑动到最底端,点击ok(在左下角) 3.进入下图页面后 ...

  5. 模拟vue的tag属性,在react里实现自定义Link

    我封装了一个简单的实现react里自定义Link的方法,方便大家使用. 因为普通组件没有metch.location.history等属性.只有在<Router>里面的<compon ...

  6. 【P2015】二叉苹果树 (树形DP分组背包)

    题目描述 有一棵苹果树,如果树枝有分叉,一定是分2叉(就是说没有只有1个儿子的结点) 这棵树共有N个结点(叶子点或者树枝分叉点),编号为1-N,树根编号一定是1. 现在这颗树枝条太多了,需要剪枝.但是 ...

  7. Linux中断管理

    CPU和外设之间的交互,或CPU通过轮询机制查询,或外设通过中断机制主动上报. 对大部分外设中断比轮询效率高,但比如网卡驱动采取轮询比中断效率高. 这里重点关注ARM+Linux组合下中断管理,从底层 ...

  8. 接口请求,上传byte数组byte[]数据异常,负数变正数/负数变63

    一.背景 最近项目中有个需求,就是需要把一个byte[]数组上传到服务端.但是我发现发送的byte数组和服务端接收的数组不一样,所有的正数在传递时正确,数组长度也没变化,但是负数变成了63或者负数全部 ...

  9. Thymeleaf的超链接与AJAX的跳转问题

    //th:href :超链接<a th:href="@{/list}"></a>//可以在其他页面跳转yt <form id="msform ...

  10. python 装饰器练习题

    1.写出完整的装饰器(不用开了带参装饰器,就是普通装饰器)语法 2.有一个计算两个数和的方法,为其添加一个确保两个参数都是int或float类型的装饰器,保证运算不会抛异常 3.有一个一次性录入人名并 ...