Loj #2324. 「清华集训 2017」小 Y 和二叉树

小Y是一个心灵手巧的OIer,她有许多二叉树模型。

小Y的二叉树模型中,每个结点都具有一个编号,小Y把她最喜欢的一个二叉树模型挂在了墙上,树根在最上面,左右子树分别在树根的左下方与右下方,且他们也都满足

这样的悬挂规则。为了让这个模型更加美观,小Y选择了一种让这棵二叉树的中序遍历序列最小的悬挂方法。所谓中序遍历最小,就是指中序遍历的结点编号序列的字典

序最小。

一天,这个模型不小心被掉在了地上,幸运的是,所有结点和边都没摔坏,但是她想不起这个模型原来是怎么悬挂的了,也就是说:她想不起来树根节点的编号了。

小Y最近忙于准备清华集训,所以没太多时间处理别的事情,她只好找到同样心灵手巧的你帮忙复原她的二叉树模型。

给定小Y的二叉树模型,结点的编号为 \(1\) ~ \(n\) ,你需要给出其可能的最小的中序遍历,方便小Y更快的摆好她的模型。

输入格式

第一行为一个正整数 \(n\) ,表示点的个数。

后接 \(n\) 行,每行若干个整数:

第 \(i+1\) 行的第一个整数为 \(k_i\) ,表示编号为 \(i\) 的结点的度数,后接 \(k_i\) 个整数 \(a_{i,j}\) ,表示编号为 \(i\) 的结点与编号为 \(a_{i,j}\) 的结

点之间有一条边。

同一行输入的相邻两个元素之间,用恰好一个空格隔开。

输出格式

输出共一行, \(n\) 个整数,表示字典序最小的中序遍历。

数据范围与提示

\(n\leq 10^6\)

假设我们知道了最优答案下的根,那么答案就很好求了。

设\(mn_i\)表示\(i\)的子树的中序遍历得到第一个点。我们可以发现,\(mn_i\)就是\(i\)子树中度数\(\leq 2\)的子节点中最小的那个。然后我们就递归:如果一个点有两个儿子,就优先走\(mn\)值小的那个;如果只有一个儿子,就要判断儿子的\(mn\)值是否比自己的值大来判断将儿子放在左边还是右边。

难点就是找根。很容易发现,答案的第一位一定是度数\(\leq 2\)的节点中最小的那个。然后我们从这个点开始递归,找到最终答案下的根。我们先找到最小的点,设为\(g\)。然后以\(g\)为根,求出\(mn\)数组。接着就是分情况讨论:

假设当前处理\(v\)节点。默认与\(v\)相邻的还没有访问到的点为\(v\)的儿子。

  • 情况1:

假设\(v\)只有一个儿子\(sn_1\),若 \(sn_1\leq mn_{sn_1}\) 则 \(sn_1\) 就作为\(v\)的父亲,递归\(sn_1\);否则\(v\)就是最终的根。
如果\(sn_1\)不作为\(v\)的父亲,那么最终答案里,\(v\)过了就是\(mn_{sn_1}\);反之\(v\)过了就是\(sn_1\)。所以这个贪心是正确的。

  • 情况2:

假设\(v\)有两个儿子\(sn_1\),\(sn_2\)(不妨设\(mn_{sn_1}<mn_{sn_2}\))。那么将\(sn_1\)作为右儿子,\(sn_2\)作为父亲,递归\(sn_2\)。

#include<bits/stdc++.h>
#define ll long long
#define N 1000005using namespace std;
inline int Get() {int x=0,f=1;char ch=getchar();while(ch<'0'||ch>'9') {if(ch=='-') f=-1;ch=getchar();}while('0'<=ch&&ch<='9') {x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}return x*f;}int n;
int r[N];
struct road {int to,nxt;
}s[N<<1];
int h[N],cnt;
void add(int i,int j) {s[++cnt]=(road) {j,h[i]};h[i]=cnt;}vector<int>ans;
int rt;
bool vis[N];
int mn[N];void Get_mn(int v,int fr) {if(r[v]<3) mn[v]=v;else mn[v]=1e9;for(int i=h[v];i;i=s[i].nxt) {int to=s[i].to;if(to==fr) continue ;Get_mn(to,v);mn[v]=min(mn[v],mn[to]);}
}int RT;
void Find_rt(int v,int fr) {int sn1=0,sn2=0;for(int i=h[v];i;i=s[i].nxt) {int to=s[i].to;if(to==fr) continue ;if(!sn1) sn1=s[i].to;else sn2=s[i].to;}if(!sn1) {RT=v;return ;}if(!sn2) {if(sn1<=mn[sn1]) Find_rt(sn1,v);else {RT=v;return ;}} else {if(mn[sn1]>mn[sn2]) swap(sn1,sn2);Find_rt(sn2,v);}
}void Print(int v,int fr) {int sn1=0,sn2=0;for(int i=h[v];i;i=s[i].nxt) {int to=s[i].to;if(to==fr) continue ;if(!sn1) sn1=to;else sn2=to;}if(mn[sn1]>mn[sn2]) swap(sn1,sn2);if(!sn2&&mn[sn1]>v) swap(sn1,sn2);if(sn1) Print(sn1,v);cout<<v<<" ";if(sn2) Print(sn2,v);
}int main() {mn[0]=1e9;n=Get();for(int i=1;i<=n;i++) {int k=Get();r[i]=k;while(k--) {int a=Get();add(i,a);}}rt=1e9;for(int i=1;i<=n;i++) if(r[i]!=3) rt=min(rt,i);Get_mn(rt,0);Find_rt(rt,0);Get_mn(RT,0);Print(RT,0);return 0;
}

转载于:https://www.cnblogs.com/hchhch233/p/10731571.html

Loj #2324. 「清华集训 2017」小 Y 和二叉树相关推荐

  1. [LOJ#2329]「清华集训 2017」我的生命已如风中残烛

    [LOJ#2329]「清华集训 2017」我的生命已如风中残烛 试题描述 九条可怜是一个贪玩的女孩子. 这天她在一堵墙钉了 \(n\) 个钉子,第 \(i\) 个钉子的坐标是 \((x_i,y_i)\ ...

  2. 【luogu P4005 清华集训2017】小Y和地铁

    题目描述 小 Y 是一个爱好旅行的 OIer.一天,她来到了一个新的城市.由于不熟悉那里的交通系统,她选择了坐地铁. 她发现每条地铁线路可以看成平面上的一条曲线,不同线路的交点处一定会设有 换乘站 . ...

  3. 「清华集训 2017」某位歌姬的故事

    题目链接 问题分析 吐槽一下这个预处理比DP还长的题-- 首先对限制从小到大排序,然后不难发现对于每一种大小限制都是独立的.离散后考虑\(F[i][j]\)表示以\(i\)结尾,上一个音高为限制大小的 ...

  4. 【费用流】loj#545. 「LibreOJ β Round #7」小埋与游乐场

    好像现在看来这个缩点的思路挺清晰啊 题目描述 有两个非负整数组成的可重集合 $A$ 和 $B$. 现在你可以对 $A$ 中至多 $k$ 个元素进行操作.操作方法为:设你准备操作且未被操作过的 $A$ ...

  5. [费用流] LOJ#545. 「LibreOJ β Round #7」小埋与游乐场

    有两种操作是有效的 lowbit(ai)>lowbit(bj)lowbit(ai)>lowbit(bj)lowbit(a_i)>lowbit(b_j) 或者 ai=bjai=bja_ ...

  6. 清华集训2017刷题记录

    2322. 「清华集训 2017」Hello world! 题意 一棵树每个点有点权,每次可以选择两个点\(s, t\),选择步长为\(k\),从\(s\)跳到\(t\)(不足\(k\)步直接到\(t ...

  7. LibreOJ545. 「LibreOJ β Round #7」小埋与游乐场【网络流】

    545. 「LibreOJ β Round #7」小埋与游乐场 [题目描述] 传送门 [题解] 网络流,我们发现lowbit之后相同的点连出的边是相同的,所以可以缩点. [代码如下] #include ...

  8. [LOJ#522]「LibreOJ β Round #3」绯色 IOI(危机)

    [LOJ#522]「LibreOJ β Round #3」绯色 IOI(危机) 试题描述 IOI 的比赛开始了.Jsp 和 Rlc 坐在一个角落,这时他们听到了一个异样的声音 -- 接着他们发现自己收 ...

  9. 「清华名师讲坛」推荐

    在「清华名师讲坛」中我们可以看见两条「桥」,一条是跨越人文与科学的桥,一条是跨越中.西的桥. 这两条桥正好说明了清华大学的特质.清华无疑地是中国理工类大学的翘楚,是中国科学研究令人生敬的殿堂,但它也拥 ...

最新文章

  1. anaconda 升级jupyter notebook_搭建 Python 轻量级编写环境(WSL2+Jupyter 自动开启本地浏览器)
  2. 动态规划备忘录方法Java_动态规划和备忘录法的区别
  3. 自己编写jQuery插件之表单验证
  4. 云电脑是什么_云电脑为什么发布新1代5G无影?带你了解PC
  5. .NET之Docker部署详细流程
  6. meanshift算法 java_Meanshift,聚类算法
  7. Ubuntu 14.04 下 Virtual Judge 的搭建
  8. Octave: 'rgb2gray' undefined error
  9. Android IPC 结篇
  10. qq空间显示手机型号android,手机qq空间发说说怎么修改/隐藏显示的手机型号?
  11. 读《Redis入门指南》2
  12. 在取证过程中,常见的一些注册表键值整理
  13. 硬件防火墙销售 Apache 遭遇DDOS攻击!!!!!!!!!!
  14. centos 的 tar 命令
  15. android 闪屏动态界面,Android开发 关于避免切换主题时闪屏的几种方式
  16. 分布式共识算法丨Raft丨Raft-Extended 论文翻译
  17. 我热爱计算机作文450字,我的国学机作文450字
  18. 全球 500 亿条数据被 Elasticsearch 勒索者删除
  19. NSDTF-DEM格式高程数据转通用的tiff格式高程数据
  20. css3实现0.5px边框、圆角渐变色边框+圆角渐变色背景

热门文章

  1. 20145227《Java程序设计》第10周学习总结
  2. Android 升级JDK及配置问题。
  3. 高质量C /C编程指南---第1章 文件机关
  4. pycharm关联mysql存储中文
  5. vue confirm确认
  6. Python3.x爬虫教程:爬网页、爬图片、自己主动登录
  7. (转)mahout推荐引擎使用hadoop
  8. php中用date()取出的当前时间查8个小时的解决方法。
  9. Java定时任务解决方案
  10. linux----------今天又遇到一个奇葩的问题,就是linux文件的权限已经是777了但是还是没有写入权限,按照下面的命令就解决了