洛谷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 ...
随机推荐
- Android 程序架构: MVC、MVP、MVVM、Unidirectional、Clean...
摘选自:GUI 应用程序架构的十年变迁:MVC.MVP.MVVM.Unidirectional.Cleanhttps://zhuanlan.zhihu.com/p/26799645 MV* in An ...
- 演化理解 Android 异步加载图片(转)
演化理解 Android 异步加载图片(转)http://www.cnblogs.com/CJzhang/archive/2011/10/20/2218474.html
- Python 爬虫入门(一)
毕设是做爬虫相关的,本来想的是用java写,也写了几个爬虫,其中一个是爬网易云音乐的用户信息,爬了大概100多万,效果不是太满意.之前听说Python这方面比较强,就想用Python试试,之前也没用过 ...
- 五、Linux学习之文件搜索命令
一.文件搜索命令locate locate 文件名 在后台数据库中按文件名搜索,搜索速度最快 /var/lib/mlocate #locate命令所搜索的后台数据库(数据库不会实时刷新,所以新建的文件 ...
- Ansible6:Playbook简单使用
目录 一个简单的示例 通过Playbook安装apache示例 playbook的构成 Hosts和Users 任务列表和action handlers tags 示例 ansbile-playboo ...
- go语言从零学起(一) -- 文档教程篇
先记录一下自己学go语言的出发点 作为一个phper,精通一门底层语言一直是努力的目标. 相对于c,c++,go语言不需要过多的关注指针,内存释放,一两行代码就能跑起一个server服务,简直不要太简 ...
- centos7.2云主机安装桌面
yum groups install "X Window System" yum groupinstall "GNOME Desktop" systemctl ...
- JavaScript 延时与定时
一.定时(setInterval) var i = 0; function hello(){ console.log(i++); } setInterval(hello,1000); // 每一秒执行 ...
- jQuery合并单元格以及还原重置
一.合并rowspan jQuery.fn.rowspan = function(colIdx) { return this.each(function(){ var that; $('tr', th ...
- 好的MongoDB学习文章链接
1.MongoDB 极简实践入门 2.MongoDB中文社区 3.极客学院Mongodb 教程