LOJ2324. 「清华集训 2017」小 Y 和二叉树【贪心】【DP】【思维】【好】
思路
首先贪新的思路是处理出以一个节点为根所有儿子的子树中中序遍历起始节点最小是多少
然后这个可以两次dfs来DP处理
然后就试图确定中序遍历的第一个节点
一定是siz<=2的编号最小的节点
这样肯定是最小的
那么来考虑从这个节点向右上和右下方扩展整棵树
一定是不能向左上或左下,不然就不优秀了
如果当前节点右除了左下有两个儿子,那么最小值小的放在右下,递归处理,大的放在右上,递归处理
如果只有一个儿子,就比较儿子和当前节点的大小并递归处理就可以了
好题啊
//Author: dream_maker
#include<bits/stdc++.h>
using namespace std;
//----------------------------------------------
//typename
typedef long long ll;
typedef pair<int, int> pi;
//convenient for
#define fu(a, b, c) for (int a = b; a <= c; ++a)
#define fd(a, b, c) for (int a = b; a >= c; --a)
#define fv(a, b) for (int a = 0; a < (signed)b.size(); ++a)
//inf of different typename
const int INF_of_int = 1e9;
const ll INF_of_ll = 1e18;
//fast read and write
template <typename T>
void Read(T &x) {
bool w = 1;x = 0;
char c = getchar();
while (!isdigit(c) && c != '-') c = getchar();
if (c == '-') w = 0, c = getchar();
while (isdigit(c)) {
x = (x<<1) + (x<<3) + c -'0';
c = getchar();
}
if (!w) x = -x;
}
template <typename T>
void Write(T x) {
if (x < 0) {
putchar('-');
x = -x;
}
if (x > 9) Write(x / 10);
putchar(x % 10 + '0');
}
//----------------------------------------------
const int N = 1e6 + 10;
int n, siz[N];
int ans[N], now[N], cnt;
int f[N][4], ch[N][4], anc[N];
int dfs1(int u, int fa) {
int res = INF_of_int;
fu(i, 1, siz[u]) {
int v = ch[u][i];
if (v == fa) {
anc[u] = i;
continue;
}
f[u][i] = dfs1(v, u);
res = min(res, f[u][i]);
}
if (siz[u] == 1 && fa) return u;
if (siz[u] == 2 && fa) return min(u, res);
return res;
}
void dfs2(int u) {
int minv = INF_of_int, fa = ch[u][anc[u]];
fu(i, 1, siz[fa]) {
int v = ch[fa][i];
if (v == u) continue;
minv = min(minv, f[fa][i]);
}
if (siz[fa] <= 2) minv = min(minv, fa);
f[u][anc[u]] = minv;
fu(i, 1, siz[u]) {
int v = ch[u][i];
if (v == fa) continue;
dfs2(v);
}
}
void getnow(int u, int fa) {
pi tmp[4];
int ind = 0;
fu(i, 1, siz[u]) {
int v = ch[u][i];
if (v == fa) continue;
tmp[++ind] = pi(f[u][i], i);
}
if (!ind) {
ans[++cnt] = u;
return;
}
sort(tmp + 1, tmp + ind + 1);
if (ind == 1) {
if (f[u][tmp[1].second] < u) {
getnow(ch[u][tmp[1].second], u);
ans[++cnt] = u;
} else {
ans[++cnt] = u;
getnow(ch[u][tmp[1].second], u);
}
} else {
getnow(ch[u][tmp[1].second], u);
ans[++cnt] = u;
getnow(ch[u][tmp[2].second], u);
}
}
void solve(int u, int fro) {
ans[++cnt] = u;
pi tmp[4];
int ind = 0;
fu(i, 1, siz[u]) {
int v = ch[u][i];
if (v == fro) continue;
tmp[++ind] = pi(f[u][i], i);
}
if (!ind) return;
sort(tmp + 1, tmp + ind + 1);
if (ind == 1) {
int nxt = ch[u][tmp[1].second];
int minv = INF_of_int;
fu(i, 1, siz[nxt])
if (ch[nxt][i] != u) minv = min(minv, f[nxt][i]);
if (minv < nxt) {
getnow(nxt, u);
} else {
solve(nxt, u);
}
} else {
getnow(ch[u][tmp[1].second], u);
solve(ch[u][tmp[2].second], u);
}
}
int main() {
Read(n);
fu(i, 1, n) {
Read(siz[i]);
fu(j, 1, siz[i]) Read(ch[i][j]);
}
dfs1(1, 0);
dfs2(1);
fu(i, 1, n) ans[i] = n;
int pos = 0;
fu(i, 1, n)
if (siz[i] <= 2) {pos = i; break;}
solve(pos, 0);
fu(i, 1, n) {
Write(ans[i]);
putchar(' ');
}
return 0;
}
LOJ2324. 「清华集训 2017」小 Y 和二叉树【贪心】【DP】【思维】【好】的更多相关文章
- loj2324 「清华集训 2017」小 Y 和二叉树
https://loj.ac/problem/2324 太智障,一开始以为中序遍历的第一个点一定是一个叶子,想了个贪心.然而,手算了一下,第一个点都过不了啊. input 5 2 3 4 1 3 3 ...
- LOJ2324「清华集训 2017」小Y和二叉树
题目链接 瞎jb贪一发就过了.首先度数<=2且编号最小的点一定是中序遍历最靠前的点,我们从这个点开始dfs一遍算出子树中度数<=2且编号最小的点记为\(f(i)\),然后从这个点开始一步一 ...
- Loj #2324. 「清华集训 2017」小 Y 和二叉树
Loj #2324. 「清华集训 2017」小 Y 和二叉树 小Y是一个心灵手巧的OIer,她有许多二叉树模型. 小Y的二叉树模型中,每个结点都具有一个编号,小Y把她最喜欢的一个二叉树模型挂在了墙上, ...
- [LOJ#2324]「清华集训 2017」小Y和二叉树
[LOJ#2324]「清华集训 2017」小Y和二叉树 试题描述 小Y是一个心灵手巧的OIer,她有许多二叉树模型. 小Y的二叉树模型中,每个结点都具有一个编号,小Y把她最喜欢的一个二叉树模型挂在了墙 ...
- loj #2325. 「清华集训 2017」小Y和恐怖的奴隶主
#2325. 「清华集训 2017」小Y和恐怖的奴隶主 内存限制:256 MiB时间限制:2000 ms标准输入输出 题目类型:传统评测方式:文本比较 题目描述 "A fight? Co ...
- [LOJ#2323]「清华集训 2017」小Y和地铁
[LOJ#2323]「清华集训 2017」小Y和地铁 试题描述 小Y是一个爱好旅行的OIer.一天,她来到了一个新的城市.由于不熟悉那里的交通系统,她选择了坐地铁. 她发现每条地铁线路可以看成平面上的 ...
- 【loj2325】「清华集训 2017」小Y和恐怖的奴隶主 概率dp+倍增+矩阵乘法
题目描述 你有一个m点生命值的奴隶主,奴隶主受伤未死且当前随从数目不超过k则再召唤一个m点生命值的奴隶主. T次询问,每次询问如果如果对面下出一个n点攻击力的克苏恩,你的英雄期望会受到到多少伤害. 输 ...
- LibreOJ #2325. 「清华集训 2017」小Y和恐怖的奴隶主(矩阵快速幂优化DP)
哇这题剧毒,卡了好久常数才过T_T 设$f(i,s)$为到第$i$轮攻击,怪物状态为$s$时对boss的期望伤害,$sum$为状态$s$所表示的怪物个数,得到朴素的DP方程$f(i,s)=\sum \ ...
- LOJ2325. 「清华集训 2017」小 Y 和恐怖的奴隶主【矩阵快速幂优化DP】【倍增优化】
LINK 思路 首先是考虑怎么设计dp的状态 发现奴隶主的顺序没有影响,只有生命和个数有影响,所以就可以把每个生命值的奴隶主有多少压缩成状态就可以了 然后发现无论是什么时候一个状态到另一个状态的转移都 ...
随机推荐
- python 使用getopt 获取配置参数
在工程中特别是稍微大一点的项目基本上都会用到配置,就会涉及到配置文件的读取,配置参数的读取. 常用的解析配置文件的是configParser,解析命令行参数的则为getopt. getopt的参数可以 ...
- MAC OS 命令行使用详解【转】
你可以整天驾驶汽车而不用知道如何修理它们,但是如果你希望当一个维护员,你就需要知道事情是如何运作的.同样的事情也发生在了 Mac OS X 上:你可以一直使用 Mac 而不用知道如何修理它,但是如果你 ...
- 好的Mysql 查询语句
select swr.id,swr.name,swr.sort as type,count(swl.id) as nums,ifnull(sum(swl.package_num),0) package ...
- codeforces246E Blood Cousins Return
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...
- php获取经纬度
<?php header("content-type:text/html;charset=utf-8"); function ipjwd() { $getIp=$_SERVE ...
- JavaScript 获取对象属性和方法
ShineJaie 原创整理,转载请注明出处. 一.获取对象属性和方法 Object.keys() 返回对象的可枚举属性和方法的名称数组. Object.getOwnPropertyNames() 返 ...
- angular指令与指令交互
app.directive('mansory',function(){ return { controller:function($scope){ this.changed = function(){ ...
- Python 使用sys模块
你已经学习了如何在你的程序中定义一次函数而重用代码.如果你想要在其他程序中重用很多函数,那么你该如何编写程序呢?你可能已经猜到了,答案是使用模块.模块基本上就是一个包含了所有你定义的函数和变量的文 ...
- UVALive - 6712 lca+dfs序线段树
题意:一棵树q次查询,每次查询给三个不同的点,要求计算到这三个点的比其他两个距离都要小的点数 题解:很明显的lca,倍增的找中点,关键是两个点的中点很好找,但是三个点不好找,我刚开始还准备分类讨论,后 ...
- LeetCode 380. Insert Delete GetRandom O(1)
380. Insert Delete GetRandom O(1) Add to List Description Submission Solutions Total Accepted: 21771 ...