洛谷P2018消息传递
传送门啦
这个树形dp就没那么简单了,运用了一下贪心的思想
不同的排序方法对应着不同的转移方程,如果我们用 $ f[x] = max(f[x] , b[i] +cnt - i + 1) $ 来进行转移就要从小往大排,才能使f[x]小,如果用 $ f[x] = max(f[x] , b[i] + i - 1) $ 来转移就要从大往小排序。
第一个转移方程:$ cnt- i $ 为还有多少个才能到它,然后+1是因为国王这个点信息需要1的时间。即他子树的大小+传递到他的时间+1(向下传递)
第二个转移方程类似。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 1005;
inline int read(){
char ch = getchar();
int f = 1 , x = 0;
while(ch > '9' || ch < '0'){if(ch == '-')f = -1;ch = getchar();}
while(ch >= '0' && ch <= '9'){x = (x << 1) + (x << 3) + ch - '0';ch = getchar();}
return x * f;
}
int n,p;
int head[maxn],tot;
int f[maxn],minn=1e9;
int ans[maxn];
struct Edge{
int to,next;
}edge[maxn << 1];
void add(int u,int v){
edge[++tot].to = v;
edge[tot].next = head[u];
head[u] = tot;
}
void dfs(int x,int fa){
int b[550],cnt = 0;
for(int i=head[x];i;i=edge[i].next){
int v = edge[i].to;
if(v != fa){
dfs(v , x);
b[++cnt] = f[v];
}
}
sort(b + 1, b + 1 + cnt );
for(int i=1;i<=cnt;i++)
f[x] = max(f[x] , b[i] + cnt - i + 1);
}
int main(){
n = read();
for(int i=2;i<=n;i++){
p = read();
add(i , p);
add(p , i);
}
for(int i=1;i<=n;i++){
memset(f , 0 , sizeof(f));
dfs(i , 0);
minn = min(minn , f[i]);
ans[i] = f[i];
}
printf("%d\n",minn+1);
for(int i=1;i<=n;i++)
if(ans[i] == minn) printf("%d ",i);
return 0;
}
第二个:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn = 1005;
inline int read(){
char ch = getchar();
int f = 1 , x = 0;
while(ch > '9' || ch < '0'){if(ch == '-')f = -1;ch = getchar();}
while(ch >= '0' && ch <= '9'){x = (x << 1) + (x << 3) + ch - '0';ch = getchar();}
return x * f;
}
int n,p;
int head[maxn],tot;
int f[maxn],minn=1e9;
int ans[maxn];
struct Edge{
int to,next;
}edge[maxn << 1];
void add(int u,int v){
edge[++tot].to = v;
edge[tot].next = head[u];
head[u] = tot;
}
bool cmp(int x , int y){
return x > y;
}
void dfs(int x,int fa){
int b[550] = {0},cnt = 0;
for(int i=head[x];i;i=edge[i].next){
int v = edge[i].to;
if(v != fa){
dfs(v , x);
b[++cnt] = f[v];
}
}
sort(b + 1, b + 1 + cnt , cmp);
for(int i=1;i<=cnt;i++)
f[x] = max(f[x] , b[i] + i - 1);
f[x] += 1;
}
int main(){
n = read();
for(int i=2;i<=n;i++){
p = read();
add(i , p); add(p , i);
}
for(int i=1;i<=n;i++){
memset(f , 0 , sizeof(f));
dfs(i , 0);
minn = min(minn , f[i]);
ans[i] = f[i];
}
printf("%d\n",minn);
for(int i=1;i<=n;i++)
if(ans[i] == minn) printf("%d ",i);
return 0;
}
洛谷P2018消息传递的更多相关文章
- 洛谷P2018 消息传递
P2018 消息传递 题目描述 巴蜀国的社会等级森严,除了国王之外,每个人均有且只有一个直接上级,当然国王没有上级.如果A是B的上级,B是C的上级,那么A就是C的上级.绝对不会出现这样的关系:A是B的 ...
- 洛谷——P2018 消息传递
P2018 消息传递 题目描述 巴蜀国的社会等级森严,除了国王之外,每个人均有且只有一个直接上级,当然国王没有上级.如果A是B的上级,B是C的上级,那么A就是C的上级.绝对不会出现这样的关系:A是B的 ...
- 洛谷 P2018 消息传递 题解
题面 总体来说是一道从下往上的DP+贪心: 设f[i]表示将消息传给i,i的子树全部接收到所能消耗的最小时间: 那么对于i的所有亲儿子节点j,我们会贪心地先给f[j]大的人传递,然后次大..... 可 ...
- 洛谷 P2018 消息传递
题目分析 贪心+树形DP 本来还以为要大费周折地换根,然后发现 \(n\) 很小,可以直接 \(O(n^2\log n)\) 枚举. 枚举每个节点作为根,用 \(f_x\) 表示走完以 \(x\) 为 ...
- 洛谷NOIp热身赛题解
洛谷NOIp热身赛题解 A 最大差值 简单树状数组,维护区间和.区间平方和,方差按照给的公式算就行了 #include<bits/stdc++.h> #define il inline # ...
- 洛谷1640 bzoj1854游戏 匈牙利就是又短又快
bzoj炸了,靠离线版题目做了两道(过过样例什么的还是轻松的)但是交不了,正巧洛谷有个"大牛分站",就转回洛谷做题了 水题先行,一道傻逼匈牙利 其实本来的思路是搜索然后发现写出来类 ...
- 洛谷P1352 codevs1380 没有上司的舞会——S.B.S.
没有上司的舞会 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description Ural大学有N个职员,编号为1~N.他们有 ...
- 洛谷P1108 低价购买[DP | LIS方案数]
题目描述 “低价购买”这条建议是在奶牛股票市场取得成功的一半规则.要想被认为是伟大的投资者,你必须遵循以下的问题建议:“低价购买:再低价购买”.每次你购买一支股票,你必须用低于你上次购买它的价格购买它 ...
- 洛谷 P2701 [USACO5.3]巨大的牛棚Big Barn Label:二维数组前缀和 你够了 这次我用DP
题目背景 (USACO 5.3.4) 题目描述 农夫约翰想要在他的正方形农场上建造一座正方形大牛棚.他讨厌在他的农场中砍树,想找一个能够让他在空旷无树的地方修建牛棚的地方.我们假定,他的农场划分成 N ...
随机推荐
- oracle的学习笔记
Oracle的介绍 1. Oracle的创始人----拉里•埃里森 2. oracle的安装 [连接Oracle步骤](](https://img2018.cnblogs.com/blog/12245 ...
- Java的I/O系统
1.File类 File类既能代表一个特定文件的名称,又能代表一个目录下的一组文件的名称. 如果我们调用不带参数的list()方法,便可以获得此File对象包含的全部列表.然而,如果我们想获得一个受限 ...
- 【bzoj4199】【Noi2015】品酒大会
题解 SA+并查集 把ht按大小倒序加入,并查集合并维护答案的变化: SAM 翻转串,求出SAM的parent树就是后缀树,两个串的最长公共后缀是他们lca的len值: 考率一个节点x,那么它子树里的 ...
- HTTP状态码的含义: 200:400:403:404:408:500:503:504
http协议的状态码 1xx(临时响应) 表示临时响应并需要请求者继续执行操作的状态码. 100(继续) 请求者应当继续提出请求.服务器返回此代码表示已收到请求的第一部分,正在等待其余部分. 101( ...
- linux中awk工具的使用
awk是一个非常好用的数据处理工具.相较于sed常常一整行处理,awk则比较倾向于一行当中分成数个“字段”处理,awk处理方式如下: $ awk '条件类型1{动作1} 条件类型2{动作2} ...' ...
- ORB算法介绍(转)
本文为原创文章,转载请注明出处:http://blog.csdn.net/yang843061497/article/details/38553765 绪论 假如我有2张美女图片,我想确认这2张图片中 ...
- lumen 使用 laravel-cors 的时候, 使用 dd 函数的解决方法
if (! function_exists('dd')) { /** * Dump the passed variables and end the script. * * @param mixed ...
- Docker图形界面管理之Shipyard
一.介绍 Shipyard基于Docker API实现的容器图形管理系统,支持container.images.engine.cluster等功能,可满足我们基本的容器部署需求. 可堆栈的Docker ...
- python 几种不同的格式化输出
1. % %是最常用的格式化输出形式,后面接类型,%s,%d,%c等等 name = input() print('I am %s' % name) 2.format format也是常用格式化输出 ...
- SQL统计每科前三名的学生的语句
偶然在论坛看到一个网友的帖子,关于他遇到一个面试题的,网站写了很多,我看了一下,结果应该是没问题的,但是为何面试官还是不满意,我想面试官可能并不是想考你真能把这道题做出来,而是看你如何简洁的通过一个s ...