jzoj3501-消息传递【换根法,树形dp】
正题
题目链接:https://jzoj.net/senior/#contest/show/3005/1
题目大意
一棵树,一个信息开始给一个人,每次得到信息的人可以选择相邻节点中的一个传递,求最短多久可以传到所有人。
解题思路
我们先考虑如何求一根的答案,farifar_ifari表示第iii个点的传递玩子树所需要的最短时间,显然对于子节点的farfarfar排个序依次传递就好了。
之后考虑换根,对于一个节点我们要求出从这个父节点不需要传递该节点时的最短时间upiup_iupi,这个值在父节点操作时可以求出。
对于dpdpdp到的节点xxx,我们将子节点的farfarfar和upxup_xupx丢进去排序,然后用一个前缀maxmaxmax和一个后缀maxmaxmax求出来所有子节点的upupup还可以顺便求出该点答案。
时间复杂度:O(nlogn):O(n\log n):O(nlogn)
codecodecode
注意这里并没有使用upupup数组,而是覆盖掉farfarfar数组来使用
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
using namespace std;
const int N=2e5+10;
struct node{int to,next;
}a[N*2];
int tot,ls[N],pre[N],aft[N];
int n,far[N],ans[N],answer;
vector<int> q[N];
void addl(int x,int y){a[++tot].to=y;a[tot].next=ls[x];ls[x]=tot;return;
}
bool cmp(int x,int y)
{return far[x]>far[y];}
void dfs(int x,int fa){int maxx=0,maxy=0;for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(y==fa) continue;dfs(y,x);q[x].push_back(y);}sort(q[x].begin(),q[x].end(),cmp);for(int i=0;i<q[x].size();i++)far[x]=max(far[q[x][i]]+i+1,far[x]);return;
}
int dp(int x,int fa){if(fa)q[x].push_back(x);sort(q[x].begin(),q[x].end(),cmp);for(int i=1;i<=q[x].size();i++)pre[i]=max(pre[i-1],far[q[x][i-1]]+i);for(int i=q[x].size();i>=1;i--)aft[i]=max(aft[i+1],far[q[x][i-1]]+i);ans[x]=max(ans[x],pre[q[x].size()]);answer=min(answer,ans[x]);for(int i=0;i<q[x].size();i++){int y=q[x][i],z;far[y]=max(pre[i],aft[i+2]-1); }for(int i=ls[x];i;i=a[i].next){int y=a[i].to;if(y==fa) continue;dp(y,x);}
}
int main()
{freopen("news.in","r",stdin);freopen("news.out","w",stdout);scanf("%d",&n);for(int i=2;i<=n;i++){int x;scanf("%d",&x);addl(i,x);addl(x,i);}answer=2147483647;dfs(1,1);dp(1,0);printf("%d\n",answer+1);for(int i=1;i<=n;i++)if(ans[i]==answer)printf("%d ",i);return 0;
}
jzoj3501-消息传递【换根法,树形dp】相关推荐
- 最大疯子树:树形DP优化:二次扫描+换根法(poj3585)
相信看这篇文的人应该是会一些简单的线性树形dp的吧-- 如果有不会的请先看看树形dp基础吧--比如这道题没有上司的舞会 其实之所以想写这篇文是因为前段时间被教练骗去叫去参加一场UESTC组织主办的线下 ...
- Full Depth Morning Show(换根法, 树形dp)
Link 题目大意: 给一颗树, 树中每个点都有一个权值, 每个边都有一个边权,定义两个点的距离为d(u, v) = (u和v的路径上边权之和乘以u和v的点权之和)现求每个点到其他所有点的距离. 思路 ...
- Educational Codeforces Round 67 (Rated for Div. 2)(D思维题 线段树/E树形dp(换根dp) 二次扫描与换根法)
心得 D写了个假算法被hack了wtcl- E据涛神说是二次扫描与换根法,看了看好像和树形dp差不多 F概率dp G费用流 回头再补 思路来源 马老师 归神 贤神等代码 http://www.mami ...
- jzoj3844-统计损失【树形dp,换根法】
正题 题目链接:https://jzoj.net/senior/#main/show/3844 题目大意 一棵树,求每条路径的点权乘积之和. 解题思路 若只考虑从xxx出发往子树的路径,那么有fx=a ...
- nssl1163-小x游世界树【树形dp,二次扫描和换根法】
正题 题目大意 一棵树,一条边的权是原本的权值减去出发点的加速. 求一个点使得这个点到所有点路径边权和最小. 解题思路 我们先求出以1为根时的答案 然后用换根法 我们从1转移到2,我们会发现 红色的部 ...
- Hile每日算法-3.31-树形dp之换根法
树形dp之换根法 周二周三真的太难了,有早课导致不能熬夜,于是就只能趁着中午的时间写一写,这几天先写点简单的东西,就当重新复习了,应该算是给初学者的知识普及,其他的过了周三再说. 首先来讲一下树的重心 ...
- P4827-[国家集训队]Crash 的文明世界【树形dp,换根法,斯特林数】
正题 题目链接:https://www.luogu.com.cn/problem/P4827 题目大意 一颗nnn个点的树,定义dis(i,j)dis(i,j)dis(i,j)表示树上i,ji,ji, ...
- 『树形DP·换根法』Accumulation Degree
题目描述 有一个树形的水系,由 N-1 条河道和 N 个交叉点组成. 我们可以把交叉点看作树中的节点,编号为 1~N,河道则看作树中的无向边. 每条河道都有一个容量,连接 x 与 y 的河道的容量记为 ...
- P4284-[SHOI2014]概率充电器【树形dp,换根法,数学期望】
正题 题目链接:https://www.luogu.com.cn/problem/P4284 题目大意 nnn个点的一棵树,每个点有pip_ipi概率通电,每个边有一定概率可以导电.求期望有电的节点 ...
最新文章
- 数据结构(C语言版) 第二章 线性表 知识梳理+作业习题详解
- php带帽接口_利用php自包含特性上传webshell
- IOS -- UICollectionView里面的cell点击,点击一个cell改变其他cell的状态
- 获取一个窗口的所有子窗口(包括嵌套) - 回复 asian 的问题
- wps单机无网络版_单平台销量破百万,这个国产单机系列要出网游,还要上主机...
- oracle rac实例切换,RAC+单实例DG的切换
- tomcat 如何跳转到apache_第二十期:基于tomcat部署jforum站点,并结合nginx实现动静分离...
- AJAX,JSON,GSON
- java sftp_JAVA 实现SFTP服务器功能
- 统计学习方法读书笔记3-感知机SVM
- 屏蔽KEmulator的内存查看功能
- 什么是软件质量管理的底层逻辑?
- JVM上篇:内存与垃圾回收篇--运行时数据区四-程序计数器
- Unity Twitter登录接入
- Chrome浏览器取色器
- set(gca,'fontsize',8);
- vue中事件监听watch
- Excel 文本转数值的方法
- python脚本实现GNSS数据自动下载
- Python之 - 使用Scrapy建立一个网站抓取器,网站爬取Scrapy爬虫教程
热门文章
- python 数据驱动接口自动化框架_python接口自动化测试 - 数据驱动DDT模块的简单使用...
- python中线程和进程_python中线程和进程的简单了解
- c语言两个长整数相加,二个超长正整数的相加
- 怎么提交 checkbox 表单_8. html form表单
- linux开机自动挂载硬盘指定权限,Linux开机自动挂载硬盘
- dma接收双缓存 stm32_「STM32学习笔记」USART 新特性
- php 派生类 构造,C++派生类的构造函数和析构函数
- memcached mysql缓存_memcached做数据库缓存
- druid字段级_Druid的数据结构
- python能做哪些客户端_Python 实现简单的客户端认证