题目链接: https://www.cometoj.com/contest/29/problem/A?problem_id=414

Aqours

题目描述

Aqours 正在 LoveLive! 决赛中表演,舞台可以看作是一棵 nn 个点的有根树,其中根节点是 1 号点,ii 号点的父亲节点为 p_ip
i

,保证 1 \le p_i < i1≤p
i

<i,而且对于 2 \le i < j \le n2≤i<j≤n 有 p_i \le p_jp
i

≤p
j

其中的叶子节点(定义为没有孩子节点的点)是与粉丝进行互动的节点,Aqours 会在这些叶子节点之间走动来与更多的粉丝互动,但是她们又要唱歌又要跳舞,要尽快节省走动时间,然后也要做到雨露均沾,所以每次要往编号更小的叶子节点走。

所以 Aqours 想知道对于每一个叶子节点 uu,离它最近的编号 < u<u 的叶子节点到它的距离是多少,若不存在则视距离为 -1。

输入描述

第一行一个正整数 n (1 \le n \le 3 \times 10^6)n(1≤n≤3×10
6
),表示树的大小。

第二行 n-1n−1 个正整数,其中第 ii 个数表示 p_{i+1}(1 \le p_{i+1} \le i)p
i+1

(1≤p
i+1

≤i)。

对于 2 \le i < j \le n2≤i<j≤n,保证 p_i \le p_jp
i

≤p
j

输出描述

每个叶子对应的答案输出一行。每行第一个数是叶子节点的编号 uu,第二个数是离他最近的编号 < u<u 的叶子节点到它的距离,若不存在则输出 -1。

要求按叶子节点编号从小到大输出。

样例输入 1

10
1 1 1 1 2 4 5 6 7
样例输出 1

3 -1
8 3
9 4
10 4

思路:

对于题面的这句话,我们可以把给定的点序列看为数的BFS序。

我们维护一个信息 dp[i] 代表距离第i个节点最近的叶子节点的距离。

我们从1到n,扫每一个叶子节点Y,我们向上(它的父节点)dfs,dfs过程中维护f的值,直到遇到一个已经访问(被其他节点dfs过得)的节点 X 。那么当前节点的答案就是 dp[X] +Y到X节点的步数。

同时还需要回溯更新dp[i] 的信息。

为什么正确?

1、我们是从1到n逐一扫描每一个叶子 节点Y,所以当一个叶子节点向上dfs的过程中遇到了一个已经放过的节点X时,X节点一定是被编号比Y小的节点更新的。所以保证了题目的要求。

2、我们在dfs过程中同时回溯维护dp[i] 的信息,就保证了dp[i] 即可以是其他节点通过先上后下到达的,也可以是下方的节点一直向上走到达的。

这样保证了dp[i] 的正确性。

细节见代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
#include <stack>
#include <map>
#include <set>
#include <vector>
#include <iomanip>
#define ALL(x) (x).begin(), (x).end()
#define rt return
#define dll(x) scanf("%I64d",&x)
#define xll(x) printf("%I64d\n",x)
#define sz(a) int(a.size())
#define all(a) a.begin(), a.end()
#define rep(i,x,n) for(int i=x;i<n;i++)
#define repd(i,x,n) for(int i=x;i<=n;i++)
#define pii pair<int,int>
#define pll pair<long long ,long long>
#define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
#define MS0(X) memset((X), 0, sizeof((X)))
#define MSC0(X) memset((X), '\0', sizeof((X)))
#define pb push_back
#define mp make_pair
#define fi first
#define se second
#define eps 1e-6
#define gg(x) getInt(&x)
#define chu(x) cout<<"["<<#x<<" "<<(x)<<"]"<<endl
using namespace std;
typedef long long ll;
ll gcd(ll a, ll b) {return b ? gcd(b, a % b) : a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
ll powmod(ll a, ll b, ll MOD) {ll ans = 1; while (b) {if (b % 2)ans = ans * a % MOD; a = a * a % MOD; b /= 2;} return ans;}
inline void getInt(int* p);
const int maxn = 3000010;
const int inf = 0x3f3f3f3f;
/*** TEMPLATE CODE * * STARTS HERE ***/
int du[maxn];
int far[maxn];
bool vis[maxn];
int n;
int ans;
int dp[maxn];
int dfs(int id,int step)
{if(vis[id]){ans=dp[id]+step;return dp[id]+1;}else{int temp=inf;dp[id]=step;vis[id]=1;if(id!=1){temp=dfs(far[id],step+1);}if(temp<dp[id])dp[id]=temp;return dp[id]+1;}
}
int main()
{//freopen("D:\\code\\text\\input.txt","r",stdin);//freopen("D:\\code\\text\\output.txt","w",stdout);gg(n);int x;repd(i,2,n){gg(x);du[x]++;far[i]=x;}repd(i,1,n){ans=-1;if(du[i]==0){dfs(i,0);printf("%d %d\n",i,ans);}}return 0;
}inline void getInt(int* p) {char ch;do {ch = getchar();} while (ch == ' ' || ch == '\n');if (ch == '-') {*p = -(getchar() - '0');while ((ch = getchar()) >= '0' && ch <= '9') {*p = *p * 10 - ch + '0';}}else {*p = ch - '0';while ((ch = getchar()) >= '0' && ch <= '9') {*p = *p * 10 + ch - '0';}}
}

转载于:https://www.cnblogs.com/qieqiemin/p/11251645.html

CCPC-Wannafly Winter Camp Day8 (Div2, onsite) A 题 Aqours (精巧的树形DP)相关推荐

  1. 2019 CCPC-Wannafly Winter Camp Day8 (Div2, onsite) 补题记录

    一篇来自ACM入门者的补题记录 最近有点懒,想着还有最后一篇博客没完成,是我最大的补题动力. 不过终于在camp过去三个月的时候完成了所有的补题博客,有点欣慰,下一个目标应该是补一补一年前暑期训练的题 ...

  2. CCPC-Wannafly Winter Camp Day8 (Div2, onsite) 补题

    A Aqours 题解: https://www.cnblogs.com/qieqiemin/p/11251645.html D:吉良吉影的奇妙计划 (暴力打表) 题目描述 吉良吉影是一个平凡的上班族 ...

  3. 2019 CCPC-Wannafly Winter Camp Day1 (Div2, onsite)(补题记录)

    一篇来自ACM入门者的补题记录 文章目录 A.机器人 B.吃豆豆 C.拆拆拆数 E.流流流动 F.爬爬爬山 I.起起落落 J.夺宝奇兵 A.机器人 题意:有两条平行线段A,B,长度从1~n,机器人一开 ...

  4. CCPC-Wannafly Winter Camp Day8 (Div2, onsite)

    Replay Dup4: 厕所是个换换脑子的好地方? 要读题啊,不要别人不做,自己就跟着不做啊 X: 读题很重要啊!什么时候才能读对题 不演队友啊 D题看错题, 直到最后一小时才看懂 很多时候要看榜单 ...

  5. CCPC-Wannafly Winter Camp Day8 (Div2, onsite) 去音乐会

    题目链接 题目描述 在冬马曜子工作室的安排下,和纱会在维也纳休养a天,然后去日本开b-a天音乐会,并以b天为一周期不断循环.而根据Knight Records的工作安排,雪菜会去外地出差c天,然后休息 ...

  6. 阔力梯的树(2020 CCPC Wannafly Winter Camp Day2 Div.12 )dsu on tree

    题解: dsu on tree dsu on tree的基本步骤就不说了 看到这题询问结点的子树问题,而且询问时离线的,首先想到的dsu on tree的这个trick. 本题的难题就是如何维护结点所 ...

  7. CCPC-Wannafly Winter Camp Day3 (Div2, onsite) I 石头剪刀布(按秩合并并查集)

    题解:每次有两个事件: y y去挑战xx,如果赢了可以坐在x x的位置,打平或者输了就要被淘汰. 询问在进行所有一类事件后,有多少种情况可以让x x现在还没有被淘汰. 对于第二类事件,我们假设x x挑 ...

  8. 2020 CCPC Wannafly Winter Camp Day3 部分题解(ACEFG)

    查看题目 A 黑色气球 题意: n个气球,每个气球高度为正整数.给你每两个气球之间的高度和,还原出所有气球的高度,保证答案唯一. 解题思路: 签到题,因为高度的范围不大,直接枚举第一个气球的高度,检测 ...

  9. CCPC-Wannafly Winter Camp Day3 (Div2, onsite) F 小清新数论 欧拉函数的利用 莫比乌斯反演 杜教筛

    F - 小清新数论 做法一:欧拉函数 #include<stdio.h> #include<bits/stdc++.h> using namespace std; #defin ...

最新文章

  1. gdb图形化调试工具总结
  2. 什么是 ABAP Field Symbol
  3. 程序人生:32条软件开发的建议和教训,值得读一读!
  4. 服务器推技术相关网址
  5. java httpclient4_httpclient4使用说明
  6. idea 注释模板_常用的模板函数
  7. # 20155337 《Android程序设计》实验四实验报告
  8. Centos6.6安装Nginx
  9. 腾讯云服务器 - 定时备份MariaDB/MySQL
  10. c语言 mysql 查询数字_c语言mysql查询数据库
  11. Java网络编程(一)- 一个简单的服务端/客户端应用程序
  12. 2020-10-24 pandas导入出现错误或者警告解决方案
  13. 批量提取html文件数据库,风越批量文本提取器
  14. 字符集本地化(locale)与输入法系列讲座-----(1) UTF-8 and Unicode FAQ
  15. 固定资产管理系统项目总结
  16. 计算机怎么通电启动,电脑通电自动开机怎么设置
  17. 卡塔尔称攻击卡塔尔通讯社黑客来自断交国
  18. 无限城app为什么服务器繁忙,鬼灭之刃:无惨为什么敢一人前往无限城,其实他最大底牌就是上五...
  19. 写一段excel VBA自动分类的代码
  20. 【HCIE-RS 天梯路】NDP

热门文章

  1. Initial load DNL_CUST_PROD0 并找出SAP S4表和CRM表的mapping关系
  2. c#二叉树 取叶子节点个数_二叉树的最小深度+完全二叉树的节点个数
  3. java实现聊天室界面javafx_java 聊天室WeChat
  4. 离散信号的希尔伯特变换的计算公式_希尔伯特变换和瞬时频率问题--连载(二)...
  5. python matplotlib画折线图出现连线混乱_python使用matplotlib模块绘制多条折线图、散点图...
  6. 帆软报表多行多条数据写入表_在线报表FineReport中多数据集如何实现层式报表...
  7. 复原 IP 地址Python解法
  8. 最长递增子序列Python解法
  9. 一维信号双边滤波器_定义图上的各向异性、动态、频谱和多尺度滤波器
  10. python编写程序判断今天是今年的第几天_C语言判断今天是今年的第几天