【Foreign】红与蓝 [暴力]
红与蓝
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】红与蓝 [暴力]的更多相关文章
- 【Foreign】Walk [暴力]
Walk Time Limit: 20 Sec Memory Limit: 256 MB Description Input Output Sample Input 3 1 2 3 1 3 9 Sa ...
- 【Foreign】朗格拉日计数 [暴力]
朗格拉日计算 Time Limit: 10 Sec Memory Limit: 128 MB Description Input Output 仅一行一个整数表示答案. Sample Input 5 ...
- 【Foreign】冒泡排序 [暴力]
冒泡排序 Time Limit: 10 Sec Memory Limit: 256 MB Description Input Output 仅一行一个整数表示答案. Sample Input 4 5 ...
- zone.js - 暴力之美
在ng2的开发过程中,Angular团队为我们带来了一个新的库 – zone.js.zone.js的设计灵感来源于Dart语言,它描述JavaScript执行过程的上下文,可以在异步任务之间进行持久性 ...
- [bzoj3123][sdoi2013森林] (树上主席树+lca+并查集启发式合并+暴力重构森林)
Description Input 第一行包含一个正整数testcase,表示当前测试数据的测试点编号.保证1≤testcase≤20. 第二行包含三个整数N,M,T,分别表示节点数.初始边数.操作数 ...
- HDU 5944 Fxx and string(暴力/枚举)
传送门 Fxx and string Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 131072/65536 K (Java/Othe ...
- 1250 Super Fast Fourier Transform(湘潭邀请赛 暴力 思维)
湘潭邀请赛的一题,名字叫"超级FFT"最终暴力就行,还是思维不够灵活,要吸取教训. 由于每组数据总量只有1e5这个级别,和不超过1e6,故先预处理再暴力即可. #include&l ...
- fragment+viepager 的简单暴力的切换方式
这里是自定义了一个方法来获取viewpager private static ViewPager viewPager; public static ViewPager getMyViewPager() ...
- 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 ...
随机推荐
- python的正则表达一
一.常用的正则表达式 1.了解正则表达式 正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符.及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种 ...
- 触发显示和隐藏 div
<script> window.onload = function(){ var oDiv1 = document.getElementById("div1"); va ...
- 让Dreamweaver支持cshtml (MVC Razor环境)
介绍:让Dreamweaver支持cshtml 正文: 如题,刚才搜了很久,都搜不到答案,幸好得到“包大人”(同事)的帮助,才得以解决. DW支持很多文件类型的代码提示,可是类型太多,不可能全部都有, ...
- Qt 在Label上面绘制罗盘
自己写的一个小小的电子罗盘的一个小程序,不过是项目的一部分,只可以贴绘制部分代码 效果如下图 首先开始自己写的时候,虽然知道Qt 的坐标系是从左上角开始的,所以,使用了算法,在绘制后,在移动回来,但是 ...
- 序列化反序列化--Xstream的使用
之前讲了fastjson的使用--将JavaBean与json对象之间互相转换. 该篇文章,教大家使用Xstream来实现XMl与JavaBean的转换. 第一步: 通过maven引入XStream的 ...
- Spark集群管理器介绍
Spark可以运行在各种集群管理器上,并通过集群管理器访问集群中的其他机器.Spark主要有三种集群管理器,如果只是想让spark运行起来,可以采用spark自带的独立集群管理器,采用独立部署的模式: ...
- Annoy解析
Annoy是高维空间求近似最近邻的一个开源库. Annoy构建一棵二叉树,查询时间为O(logn). Annoy通过随机挑选两个点,并使用垂直于这个点的等距离超平面将集合划分为两部分. 如图所示,图中 ...
- WebSocket 与 HTTP/2
个人笔记 WebSocket WebSocket 是一个双向通信协议,它在握手阶段采用 HTTP/1.1 协议(暂时不支持 HTTP/2). 握手过程如下: 首先客户端向服务端发起一个特殊的 HTTP ...
- UVA 11881 Internal Rate of Return(数学+二分)
In finance, Internal Rate of Return (IRR) is the discount rate of an investment when NPV equals zero ...
- iOS-UIImageView播放动画
NSArray *gifArray = [NSArray arrayWithObjects:[UIImage imageNamed:@"lanya1"],[UIImage imag ...