传送门

UPD:之前可能对白色变无色的过程讲的不是很清楚,已经补充


显然在双方绝顶聪明的情况下,黑色不可能赢

首先考虑树上一个白色的点都没有的情况:

1、如果树上有一个点的度数\(\geq 4\),白色必赢,只需要第一次将这一个点染成白色,接着随便染它的两个邻居就可以达成目标

2、如果树上有一个点的度数\(=3\),且它所连的\(3\)个点之间至少有\(2\)个点不是叶子节点,白色必赢,只需要第一次染这一个点,第二次染它的一个非叶子邻居,第三次就一定至少存在一个未被染色的点与这两个相邻。

那么剩下的情况,树的形态只会是下图中的三种

但是还没完(我以为到这里就完了结果WA2被Tutorial点名)

最重要的3、如果树的形态是上面的图中最下面的那一种,而且总点数为奇数,那么白色必赢

图长下面这样,中间的……省略的是一条链,编号从左往右递增。

白色最开始染\(2\)号点,黑色如果染\(3\)号点白色直接染\(1\)号点,所以黑色必须染\(1\)号点。此时白色染\(4\)号点,黑色又只能染\(3\)号点……如是白色染到\(2N\)号点,黑色染\(2N-1\)号点之后,白色染\(2N+1\)号点,那么最右边就会有两个未被染的点,白色就赢了

其余的情况显然都是Draw的

然后考虑已经被染成白色的点的影响,最开始天真的我想直接各种特判过掉,结果WA14不晓得怎么回事

我们已经考虑了树上没有被染成白色的点的所有情况,那么能否将一个已经被染成白色的点等价为若干未被染成白色的点?实际上是可以的

假设下图中\(1\)号点在原树上是一个白色点,那就在保留它原来的邻居的基础上给它额外连上\(3\)个点,连成下面的\(ABCD\)结构

原图\(1\)号点对应新图的\(A\)号点,原图上\(1\)号点跟哪些点连了边,新图上\(A\)号点也和它们连边,然后在下面挂上\(BCD\)三个点

对于执白色的人来说,如果TA在某一回合涂白了\(A\)号点,这个时候如果执黑色者不涂黑\(B\)号点,那么执白色者将会在下一回合涂白\(B\)号点,对于\(CD\)两个点,白色就一定可以涂白其中一个,白色就赢了

所以执黑色者只能涂黑\(B\)号点。而这个时候\(BCD\)三个点对于胜负已经没有影响了,可以直接砍掉这三个点,就相当于白色直接涂白了\(A\)号点,也就是涂白了原图的\(1\)号点,然后又来到白色的回合。

#include<bits/stdc++.h>
//This code is written by Itst
using namespace std; inline int read(){
int a = 0;
char c = getchar();
bool f = 0;
while(!isdigit(c)){
if(c == '-')
f = 1;
c = getchar();
}
while(isdigit(c)){
a = (a << 3) + (a << 1) + (c ^ '0');
c = getchar();
}
return f ? -a : a;
} const int MAXN = 1e6 + 9;
struct Edge{
int end , upEd;
}Ed[MAXN << 1];
int head[MAXN] , in[MAXN] , N , cntEd , cnt;
char s[MAXN]; inline void addEd(int a , int b){
Ed[++cntEd].end = b;
Ed[cntEd].upEd = head[a];
head[a] = cntEd;
++in[a];
} int main(){
for(int T = read() ; T ; --T){
N = read();
cntEd = 0;
memset(head , 0 , sizeof(int) * (N + 1));
memset(in , 0 , sizeof(int) * (N + 1));
for(int i = 1 ; i < N ; ++i){
int a = read() , b = read();
addEd(a , b);
addEd(b , a);
}
scanf("%s" , s + 1);
if(N < 3){
puts("Draw");
continue;
}
if(N == 3){
int cnt = 0;
for(int i = 1 ; i <= N ; ++i)
cnt += s[i] == 'W';
puts(cnt >= 2 ? "White" : "Draw");
continue;
}
bool ifans = 0;
int cnt1 = 0;
for(int i = 1 ; i <= N ; ++i)
if(s[i] == 'W'){
addEd(i , ++N);
head[N] = 0;
addEd(N , i);
in[N] = 3;
}
for(int i = 1 ; !ifans && i <= N ; ++i)
if(in[i] > 3)
ifans = 1;
else
if(in[i] == 3){
int cnt = 0;
for(int j = head[i] ; j ; j = Ed[j].upEd)
cnt += in[Ed[j].end] >= 2;
ifans = cnt >= 2;
++cnt1;
}
if(cnt1 == 2 && (N & 1))
ifans = 1;
puts(ifans ? "White" : "Draw");
}
return 0;
}

CF1110G Tree-Tac-Toe 博弈论、构造的更多相关文章

  1. Principle of Computing (Python)学习笔记(7) DFS Search + Tic Tac Toe use MiniMax Stratedy

    1. Trees Tree is a recursive structure. 1.1 math nodes https://class.coursera.org/principlescomputin ...

  2. POJ 2361 Tic Tac Toe

    题目:给定一个3*3的矩阵,是一个井字过三关游戏.开始为X先走,问你这个是不是一个合法的游戏.也就是,现在这种情况,能不能出现.如果有人赢了,那应该立即停止.那么可以知道X的步数和O的步数应该满足x= ...

  3. 【leetcode】1275. Find Winner on a Tic Tac Toe Game

    题目如下: Tic-tac-toe is played by two players A and B on a 3 x 3 grid. Here are the rules of Tic-Tac-To ...

  4. 2019 GDUT Rating Contest III : Problem C. Team Tic Tac Toe

    题面: C. Team Tic Tac Toe Input file: standard input Output file: standard output Time limit: 1 second M ...

  5. CodeForces - 1098.DIV1.C: Construct a tree(贪心,构造)

    Misha walked through the snowy forest and he was so fascinated by the trees to decide to draw his ow ...

  6. Atcoder Regular Contest 117 D - Miracle Tree(分析性质+构造)

    Atcoder 题面传送门 笑死,阴间语文作业到现在还没写完,为了在这个点保持精神,我只好来颓篇题解辣 我们考虑探究一下怎么最小化 \(\max\limits_{i=1}^nE_i\),我们假设 \( ...

  7. [CareerCup] 17.2 Tic Tac Toe 井字棋游戏

    17.2 Design an algorithm to figure out if someone has won a game oftic-tac-toe. 这道题让我们判断玩家是否能赢井字棋游戏, ...

  8. Epic - Tic Tac Toe

    N*N matrix is given with input red or black.You can move horizontally, vertically or diagonally. If ...

  9. python 井字棋(Tic Tac Toe)

    说明 用python实现了井字棋,整个框架是本人自己构思的,自认为比较满意.另外,90%+的代码也是本人逐字逐句敲的. minimax算法还没完全理解,所以参考了这里的代码,并作了修改. 特点 可以选 ...

  10. ACM-Team Tic Tac Toe

    我的代码: #include <bits/stdc++.h> using namespace std; int main() { char a[3][3]; int i,j=0; for( ...

随机推荐

  1. 虚拟 DOM

    虚拟DOM :virtual dom(以下简称vdom,是vue和react的核心),使用比较简单. 一,vdom是什么,为何会存在vdom 1,什么是vdom:用js模拟DOM结构,DOM操作非常‘ ...

  2. 活字格Web应用平台学习笔记 8 - 查询记录

    基础教程只剩一点点了,学完算了. 这一课的目标是:查询记录 这个操作的原理很简单,增加一个表格,绑定“部门”那个数据,然后增加一个命令,点击查询. 绑定命令: 完成后的实际界面,查询前面是个下拉框: ...

  3. 自定义控件详解(三):Canvas效果变换

    Canvas 画布 从前面我们已经知道了 Canvas 类可以绘出 各种形状. 这里学习一下Canvas 类的变换效果(平移,旋转等) 首先需要了解一下Canvas 画布, 我们用Canvas.Dra ...

  4. Android常用数据类型转换

    String转int.float.double.byte[].bitmap Int i = Integer.parseInt(str); Float f = Float.parseFloat(str) ...

  5. 洗礼灵魂,修炼python(11)--python函数,模块

    前面的章节你如果看懂了,基本算是入门了七八了,不过如果你以为python就这么点东西,你觉得很简单啊,那你就错了,真正的东西在后面,前面我说的几大核心其实也不是多么高深多么厉害的,那些东西是基础很常用 ...

  6. 移动端上拉加载,下拉刷新效果Demo

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. EntityFramework Code-First 简易教程(八)-------一对一

    配置一对一(One-to-One)关系: 两个实体中,如果一个实体的一个实例与另一个实体相关,则我们就叫做一对一关系 查看如下代码: public class Student { public Stu ...

  8. Linux系统将http转为https

    想把网站由http访问转变为https访问并没有想象中那么难,网上查了一些资料,想要转为https需要SSL安全证书,这里推荐一款景安网络的证书,可以免费试用一年时间,自己拿来实践还是很不错的选择. ...

  9. linux网关设置

    1.linux中eth0为外网ip.外网网关.外网DNS设置,eth1为内网ip”172.22.0.0/16“不设置网关.DNS. 2.启动linux内核中的IP转发功能 执行vim命令编辑sysct ...

  10. MATLAB数值分析实验

    1.用Newton迭代法求方程   的第一个正根. 作者:凯鲁嘎吉 - 博客园http://www.cnblogs.com/kailugaji/ newton.m: function x1=newto ...