红与蓝

Time Limit: 10 Sec  Memory Limit: 256 MB

Description

  

Input

  

Output

  

Sample Input

  2
  2
  0 1
  -1 -1
  2
  0 1
  -1 1

Sample Output

  1 2
  -1

HINT

  

Main idea

  每个节点有红色、蓝色或者无色,给定了若干叶子节点的颜色,非叶子节点的颜色定义为所有儿子中颜色出现次数最多的一个,若一样则无色。叶子节点无色则可以染色,红色先手,蓝色接着轮流染色,最后若根为红色则胜利否则失败。胜利的话还要求输出可行方案。

Source

  我们可以先O(n)求出在不动叶子节点情况下每一个点的颜色,由于每个一个点只有奇数个儿子,且红色先手。那么这时候如果根节点为红色或者无色则必胜,蓝色则必败

  然后我们分情况讨论,蓝色就直接输出“-1”,结束即可。如果根是红色的话,显然染色对于答案是没有什么影响的,所以所有无色的叶子节点都可以是解

  现在我们来讨论根无色的情况:我们计算每一个点中儿子的蓝色个数和红色个数,如果一个点是 (蓝色,且蓝色个数=红色个数+1) 或者 (无色,蓝色个数=红色个数)则可以往下递归,找到叶子节点为无色则可以是解。我们来解释一下:

  1. 蓝色,蓝色个数=红色个数+1:如果往下走有可染色的叶子节点,那么必然逼着蓝色接着染,否则蓝色就输了。这个点的颜色就会是:无、蓝、无……由于红色先手,所以最后这个点是可以变成无色的,因为递归做到这里,所以这个点的父亲节点是白色的,然后这个点变为了白色,它的父亲就少了一个蓝色儿子,就变成红色了。

  2. 无色,蓝色个数=红色个数:如果往下走有可染色的叶子节点,那么这一条无色链上都会变成红色的,显然可行。

  这样我们暴力递归往下讨论,就解决了这个问题。

Code

 #include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std; const int ONE = ; int T;
int n,x,root;
int Val[ONE];
int next[ONE],first[ONE],go[ONE],tot;
int ans_num,Ans[ONE]; void Add(int u,int v)
{
next[++tot]=first[u]; first[u]=tot; go[tot]=v;
} int get()
{
int res,Q=; char c;
while( (c=getchar())< || c>)
if(c=='-')Q=-;
if(Q) res=c-;
while((c=getchar())>= && c<=)
res=res*+c-;
return res*Q;
} void Deal_first(int u)
{
for(int e=first[u];e;e=next[e])
{
int v=go[e];
Deal_first(v);
Val[u] += Val[v];
}
if(Val[u] < ) Val[u] = -;
else if(Val[u] > ) Val[u] = ;
} void Dfs(int u)
{
if(!Val[u] && !first[u])
Ans[++ans_num] = u; for(int e=first[u];e;e=next[e])
{
int v=go[e];
int tot=;
for(int i=first[v];i;i=next[i])
tot+=Val[go[i]];
if(tot== || tot==-) Dfs(v);
}
} void Solve()
{
n=get();
tot=; memset(first,,sizeof(first));
for(int i=;i<=n;i++)
{
x=get();
if(!x) root=i;
else Add(x,i);
} for(int i=;i<=n;i++)
{
Val[i]=get();
if(Val[i]==) Val[i]=;
else if(Val[i]==) Val[i]=-;
else Val[i]=;
} Deal_first(root);
if(Val[root] < )
{
printf("-1");
return;
}
else
{
ans_num=;
if(Val[root]==) Dfs(root),sort(Ans+,Ans+ans_num+);
if(Val[root]==) for(int i=;i<=n;i++) if(!Val[i] && !first[i]) Ans[++ans_num]=i; printf("%d ",ans_num);
for(int i=;i<=ans_num;i++)
printf("%d ",Ans[i]);
}
} int main()
{
T=get();
while(T--)
Solve(),printf("\n");
}

  

【Foreign】红与蓝 [暴力]的更多相关文章

  1. 【Foreign】Walk [暴力]

    Walk Time Limit: 20 Sec  Memory Limit: 256 MB Description Input Output Sample Input 3 1 2 3 1 3 9 Sa ...

  2. 【Foreign】朗格拉日计数 [暴力]

    朗格拉日计算 Time Limit: 10 Sec  Memory Limit: 128 MB Description Input Output 仅一行一个整数表示答案. Sample Input 5 ...

  3. 【Foreign】冒泡排序 [暴力]

    冒泡排序 Time Limit: 10 Sec  Memory Limit: 256 MB Description Input Output 仅一行一个整数表示答案. Sample Input 4 5 ...

  4. zone.js - 暴力之美

    在ng2的开发过程中,Angular团队为我们带来了一个新的库 – zone.js.zone.js的设计灵感来源于Dart语言,它描述JavaScript执行过程的上下文,可以在异步任务之间进行持久性 ...

  5. [bzoj3123][sdoi2013森林] (树上主席树+lca+并查集启发式合并+暴力重构森林)

    Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数 ...

  6. HDU 5944 Fxx and string(暴力/枚举)

    传送门 Fxx and string Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Othe ...

  7. 1250 Super Fast Fourier Transform(湘潭邀请赛 暴力 思维)

    湘潭邀请赛的一题,名字叫"超级FFT"最终暴力就行,还是思维不够灵活,要吸取教训. 由于每组数据总量只有1e5这个级别,和不超过1e6,故先预处理再暴力即可. #include&l ...

  8. fragment+viepager 的简单暴力的切换方式

    这里是自定义了一个方法来获取viewpager private static ViewPager viewPager; public static ViewPager getMyViewPager() ...

  9. ACM: Gym 101047M Removing coins in Kem Kadrãn - 暴力

     Gym 101047M Removing coins in Kem Kadrãn Time Limit:2000MS     Memory Limit:65536KB     64bit IO Fo ...

随机推荐

  1. Linux 下 PHP 扩展Soap 编译安装

    1.进入 PHP 的软件包 pdo 扩展目录中(注:不是 PHP 安装目录) [root@tester /]# /home/tdweb/php-5.4.34/ext/soap 执行 phpize 命令 ...

  2. Qt Qwdget 汽车仪表知识点拆解1 速度表示

    先贴上效果图,注意,没有写逻辑,所以这些都是乱动的 这里线主要说一下中间显示速度的显示制作的方式,在这里,自己专门写了一个数字的仪表 考虑的一般的汽车是没有办法把瞬时速度提升到四位数的,所以我这里就放 ...

  3. Qt 加载Leap motion 手势识别软件 二次开发 hello world

    研发需要对收拾是被进行精确定位,实现收拾的识别,和在虚拟现实中精确的显示手势在实际世界中的位置. 开始使用的Qt mingw的版本开发,总是函数没有定义,最后发现是leap sdk中需要代育vs的库文 ...

  4. restAssured + TestNG测试接口,以下是一个get 请求。

    package Elaine.Test.G.APITest; import org.testng.Assert;import org.testng.annotations.BeforeTest;imp ...

  5. 扩展欧几里得 求ax+by == n的非负整数解个数

    求解形如ax+by == n (a,b已知)的方程的非负整数解个数时,需要用到扩展欧几里得定理,先求出最小的x的值,然后通过处理剩下的区间长度即可得到答案. 放出模板: ll gcd(ll a, ll ...

  6. 父窗体和子窗体的显示,show&showdialog方法

    showdialog(): 子窗体弹出后,不能对父窗体进行操作.show()可以. 具体原理: 1.在调用Form.Show方法后,Show方法后面的代码会立即执行  2.在调用Form.ShowDi ...

  7. NHibernate3.3.3 学习笔记1

    前言 昨天在园友的介绍下,我找了一本学习NHibernate的书:<NHibernate 3 Beginner’s Guide>. 第一章我直接跳过了,因为是英文版的看起来很吃力,且第一章 ...

  8. 《SQL入门经典》总结

    <SQL入门经典>这本书从考试前就开了个头,一直到前两天才看完,拉的战线也够长的.放假来了,基本上什么内容都不记得了.好不容易看完了,就赶紧总结一下吧! 该书分为两大部分,第一部分是第1~ ...

  9. Centos7安装GUI桌面

    2018-03-02 21:37:48 Centos7-1708成功 yum -y groupinstall "GNOME Desktop"

  10. EXEL文件转成简书MD表格

    EXEL文件转成简书MD表格 0.1.3 mac: https://github.com/fanfeilong/exceltk/blob/master/pub/exceltk.0.1.3.pkg wi ...