YOUSIKI 在 noip2016 的一道《天天爱跑步》的题爆零后,潜心研究树上问题,成为了一代大师,于是皮皮妖为了测验他,出了一道题,名曰《跑步爱天天》。

有一个以 1 为根的有根树,初始每个点都有个警卫,每个警卫会按深度优先的顺序周期性的巡逻以其初始点为根的子树(详见样例解释),一个时刻走且仅走一条边。

YOUSIKI 初始在 x 点,他要到根结点拜访皮皮妖,他会沿着最短路径走,一个时刻走且仅走一条边,当他走到这个点时,如果遇到了警卫,他会消耗 1点妖气将这个警卫杀死,杀死后的警卫就不会在以后的路程中出现。

那么 YOUSIKI 需要消耗几点妖气才能拜访到皮皮妖呢?

输入格式

第一行一个数字 T,表示有 T 组数据。

对于每组数据,第一行一个整数 n,表示树有 n个结点。

接下来 n 行,第 i 行有一个整数 k,表示 i号点儿子个数,接下来 k 个整数,表示 k 个有序儿子 (“有序” 的含义详见样例解释)。

最后一行一个整数 x,表示 YOUSIKI 的出发点。

输出格式

输出 T 行,每行一个整数表示答案。

数据范围

对于 20% 的数据,n≤100。

对于 40% 的数据:n≤2000。

对于另外 10% 的数据:树高 ≤5。

对于另外 10% 的数据:树是一条链。

对于 100% 的数据:T≤10,n≤500000。

样例解释

为了方便,我们把初始在 iii 号点的警卫称为警卫 iii。

警卫 1 的一个周期内的巡逻路线为:1->2->4->2->5->2->1->3->6->3->1。

警卫 2 的一个周期内的巡逻路线为:2->4->2->5->2。

警卫 3 的一个周期内的巡逻路线为:3->6->3。

警卫 4,5,6 一直不动。

YOUSIKI 的路线为:6->3->1。

YOUSIKI 初始在 6 号点,需要杀掉警卫 6。第一时刻他在 3 号点,虽然他和警卫 3 对穿过去,但是由于没有在点上相遇,所以不算相遇。第二时刻他在 1 号点,此时 111 号点没有警卫。

注意

  1. 警卫的巡逻是周期性的,例如,初始在 2 号点警卫的巡逻路线为:2->4->2->5->2->4->2->5->2->4->2->5->2->...

  2. 输入格式中的 “有序” 指的是比如 1 号点的儿子先输入的 2 再输入的 3,那么 1 号点巡逻时就要先巡逻 2 再巡逻 3。

样例输入

1
6
2 2 3
2 4 5
1 6
0
0
0
6

样例输出

1

我们先把整个树 dfs 一遍,遇到一个点就把这个点记录到一个数组后边,
即求出了树的欧拉序,显然如果不考虑循环的话,guard是在这个序列上每次往后走一个,起始位置就是第i个点第一次出现的位置

假设 YOUSIKI 现在走到了 x 点,过了 t 秒,那么我们在这个序列上遍历 x 出现的所有位置,
并查看这个位置往前 t 个是否为 x 的祖先,如果是,把那个祖先标为1,表示已被消灭

坑点1:因为要按输入顺序遍历子节点,而链式前向星建出的图是从后往前的

所以要把加边的顺序反过来

坑点2:相遇的警卫只能是往下走的,且起始位置为第一个出现的i,所以第前t个

祖先必须是第一个出现的

 

 #include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
struct Node
{
int next,to;
}edge[];
int num,head[],dep[],dfn[];
int s,cl,tot,t[],n,ans,f[],st[];
bool vis[],mark[];
int gi()
{
char ch=getchar();
int x=;
while (ch<''||ch>'') ch=getchar();
while (ch>=''&&ch<='')
{
x=x*+ch-'';
ch=getchar();
}
return x;
}
void add(int u,int v)
{
num++;
edge[num].next=head[u];
head[u]=num;
edge[num].to=v;
}
void dfs(int x)
{int i;
dfn[++tot]=x;f[tot]=;
mark[x]=(x==s);
for (i=head[x];i;i=edge[i].next)
{
int v=edge[i].to;
dep[v]=dep[x]+;
dfs(v);
if (mark[v]) mark[x]=;
dfn[++tot]=x;f[tot]=;
}
if (mark[x]) t[x]=cl++;
}
int main()
{int T,i,j,k,x;
cin>>T;
while (T--)
{
memset(head,,sizeof(head));
num=;cl=;tot=;
memset(mark,,sizeof(mark));
memset(dep,,sizeof(dep));
memset(t,,sizeof(t));
memset(f,,sizeof(f));
n=gi();
for (i=;i<=n;i++)
{
k=gi();
for (j=;j<=k;j++)
{
st[j]=gi();
}
for (j=k;j>=;j--)
add(i,st[j]);
}
s=gi();
dep[]=;
dfs();
ans=;
memset(vis,,sizeof(vis));
int u,v;
for (i=;i<=tot;i++)
{
if (mark[u=dfn[i]]&&i>t[u]&&f[i-t[u]])
if (mark[v=dfn[i-t[u]]]&&dep[v]<=dep[u])
if (vis[v]==)
{
ans++;
vis[v]=;
}
}
cout<<ans<<endl;
}
}

计蒜客NOIP模拟赛4 D2T2 跑步爱天天的更多相关文章

  1. 计蒜客NOIP模拟赛(2) D2T2紫色百合

    [问题描述] “牵着你的手的是她,路边开满了紫色的百合花……” 你从梦中醒来,却依然忘不了梦中的她百合花,每朵百合花都有一个权值,在二进制下写成一行‘1’,第i朵紫色百合的权值在二进制下写成i个‘1’ ...

  2. 计蒜客NOIP模拟赛D2T2 直线的交点

    伦伦刚刚在高中学习了解析几何,学会了计算两条直线的交点.这天,老师给她布置了一道作业.在平面上有 nnn 条直线,他们之间有若干交点.给定一对平板(两条平行的直线),问这有多少对直线,他们的交点在这一 ...

  3. 计蒜客NOIP模拟赛6 D1T1Diamond-square

    Diamond-square 算法是一种能够用于生成噪声的算法,现在我们考虑这个算法的一个变种. 你有一个 2^n\times 2^n2​n​​×2​n​​ 的网格,一共有 (2^n+1)^2(2​n ...

  4. 计蒜客NOIP模拟赛4 D2T1 鬼脚图

    鬼脚图,又称画鬼脚,在日本称作阿弥陀签,是一种经典游戏,也是一种简易的决策方法,常常用来抽签或决定分配组合. 下图就是一张鬼脚图,其包含若干条竖线和若干条横线.请注意,横线只能水平连接相邻的两条竖线, ...

  5. 计蒜客 NOIP模拟赛(3) D1T1火山喷发

    火山喷发对所有附近的生物具有毁灭性的影响.在本题中,我们希望用数值来模拟这一过程. 在环境里有 nnn 个生物分别具有 A1,A2,⋯,An​​点生命值,一次火山喷发总计 M轮,每轮造成 1点伤害,等 ...

  6. 计蒜客NOIP模拟赛(2) D1T1邻家男孩

    凡是一个具有领导力的孩子.现实生活中他特别喜欢玩一个叫做 UNO 的纸牌游戏,他也总是带着其他小朋友一起玩,然后战胜他们.慢慢地,他厌倦了胜利,于是准备发明一种新的双人纸牌游戏. 初始时,每个人手中都 ...

  7. 计蒜客NOIP模拟赛5 D1T1 机智的 AmyZhi

    那年一个雨季,AmyZhi 在校门外弯身买参考书. 这时 SiriusRen 走过来,一言不合甩给她一道“自认为”很难的题: --------------- 给你一个数字 NN(NN 的范围是 11  ...

  8. 计蒜客NOIP模拟赛4 D1T3 小X的佛光

    小 X 是远近闻名的学佛,平日里最喜欢做的事就是蒸发学水. 小 X 所在的城市 X 城是一个含有 N 个节点的无向图,同时,由于 X 国是一个发展中国家,为了节约城市建设的经费,X 国首相在建造 X ...

  9. 计蒜客NOIP模拟赛4 D1T2小X的密室

    小 X 正困在一个密室里,他希望尽快逃出密室. 密室中有 N 个房间,初始时,小 X 在 1 号房间,而出口在 N 号房间. 密室的每一个房间中可能有着一些钥匙和一些传送门,一个传送门会单向地创造一条 ...

随机推荐

  1. Alpha冲刺No.9

    一.站立式会议 继续解决真实手机中的问题,如果不能解决,请教助教学姐 数据库备忘录的获取和上传 细化界面设计 二.项目实际进展 用一种奇怪的方式解决了真实手机中的问题,在总结里细说. 完成数据库备忘录 ...

  2. Python 图片转字符画

    Python 图片转字符画 一.课程介绍 1. 课程来源 原创 2. 内容简介 本课程讲述怎样使用 Python 将图片转为字符画 3. 前置课程 Python编程语言 Linux 基础入门(新版) ...

  3. 《招一个靠谱的移动开发》iOS面试题及详解(上篇)

    以下问题主要用于技术的总结与回顾 主要问题总结 单例的写法.在单利中创建数组应该注意些什么. NSString 的时候用copy和strong的区别. 多线程.特别是NSOperation 和 GCD ...

  4. 集合Collection总览

    前言 声明,本文使用的是JDK1.8 从今天开始正式去学习Java基础中最重要的东西--->集合 无论在开发中,在面试中这个知识点都是非常非常重要的,因此,我在此花费的时间也是很多,得参阅挺多的 ...

  5. react-native-image-picker 运用launchCamera直接调取摄像头的缺陷及修复

    在前几天用react-native进行android版本开发当中,用到了"react-native-image-picker"的插件:根据业务的需求:点击按钮-->直接调取摄 ...

  6. emqtt 试用(一)安装和测试

    一.安装 http://emqtt.io/docs/v2/getstarted.html http://emqtt.io/docs/v2/advanced.html http://emqtt.io/d ...

  7. kubernetes入门(04)kubernetes的核心概念(1)

    一.ReplicationController/ReplicaSet 在Kubernetes集群中,ReplicationController能够确保在任意时刻,指定数量的Pod副本正在运行.如果Po ...

  8. shiro的sessionManager类继承结构及主要类方法

    shiro1.3.2 sessionManage的作用是对会话进行管理. 1.类结构 2.主要接口介绍 SessionManager: 包括两个方法,一个是新建会话,一个是通过key获取会话 Vali ...

  9. Python入门之迭代器/生成器/yield的表达方式/面向过程编程

    本章内容 迭代器 面向过程编程 一.什么是迭代 二.什么是迭代器 三.迭代器演示和举例 四.生成器yield基础 五.生成器yield的表达式形式 六.面向过程编程 ================= ...

  10. python/Django(增、删、改、查)操作

    python/Django(增.删.改.查)操作 我们要通过pycharm中的Django模块连接MySQL数据库进行对数据的操作. 一.创建Django项目(每创建一个项目都要进行以下设置) 1.如 ...