思路

分析最优解性质

  • 任意两个点高度至多相差1
  • 任取一条最优滑雪路径。最后反复出现的点一定最多仅有2个。其余的路径上的点互不相同
    • 若不然,可以将其余的重复点构成的路径加到这两个点的反复中。
  • 如果能反复,考虑在点uuu开始进行反复。开始点为点v。则最长能滑动的总路径为2hv−hu2h_v - h_u2hv​−hu​这是因为从点v到点u多余能量hv−huh_v - h_uhv​−hu​,在u点开始与其邻居进行反复,直到能量消耗为0.至此,共消耗能量2(hv−hu)2 (h _v - h_u)2(hv​−hu​)。加上从u点到doge能滑动最长的距离huh_uhu​。
  • 由上式可见,若huh_uhu​较小,则滑动的距离较大。因此对每个结点找其能到达的高度最低的u点,如果能找到答案为上述式子,否则答案为自身的高度

逆向考察

  • 对上述u点,其必须满足至少有一个邻居与其有同样的高度。对于这样的点对u,vu,vu,v,v是u的与其相同高度的邻居。其到达它们最近的doge的路径互不相交。因此∑u∈Shu\sum_{u \in S} h_uu∈S∑​hu​较小。可以证明其是O(n)O(n)O(n)级别的。于是不同的huh_uhu​个数是n\sqrt{n}n​级别的。
  • 对每种可能的高度对应的结点考察其能够到达的所有结点。

实现(官方)

  • 先使用多源bfs求出所有点的高度。
while(!q.empty()){int x=q.front();q.pop();for(auto c:adj[x]){if(d[c] == -1){d[c]=d[x]+1;q.push(c);}}}
  • 利用h数组记录可行的高度i是几号高度,利用g数组记录z号高度的实际高度。
     for(int i=1; i<=n ;i++){f[d[i]].push_back(i);for(auto c:adj[i]){if(d[c]==d[i] && c>i){use[d[i]]=true;}}}for(int i=0; i<=n ;i++){if(use[i]){g[++z]=i;h[i]=z;}}/*
  • ans[i][z]表示i号结点到达z号高度满足邻居有相同z号高度的结点所需要的最少初始能量,其中z的取值是n\sqrt{n}n​级别的。
  • 将结点按高度进行分层。假设下一层所需要到达的每一种可能高度的最低能量已经求出,下一层对上一层按照公式:
    ans[x][i]=min(ans[x][i],max(0,ans[c][i]−1))ans[x][i]=min(ans[x][i],max(0,ans[c][i]-1))ans[x][i]=min(ans[x][i],max(0,ans[c][i]−1))
    其中c是下一层结点,x是当前层结点。
             for(auto c:adj[x]){if(d[c]==d[x]-1){for(int i=1; i<=z ;i++) ans[x][i]=min(ans[x][i],max((ll)0,ans[c][i]-1));}}
  • 同层结点的转移,利用up and down dp,通过两次dfs(待学习)
    ans[c][i]=min(ans[c][i],ans[id][i]+1)ans[c][i]=min(ans[c][i],ans[id][i]+1)ans[c][i]=min(ans[c][i],ans[id][i]+1)
    其中id是c的邻居,对每种高度i循环执行
void dfs(int id,int p){vis[id]=true;for(auto c:adj[id]){if(c==p || d[c]!=d[id]) continue;dfs(c,id);for(int i=1; i<=z ;i++){ans[id][i]=min(ans[id][i],ans[c][i]+1);}ans[id][h[d[id]]]=0;}}void dfs2(int id,int p){for(auto c:adj[id]){if(c==p || d[c]!=d[id]) continue;for(int i=1; i<=z ;i++){ans[c][i]=min(ans[c][i],ans[id][i]+1);}ans[c][h[d[c]]]=0;dfs2(c,id);}}
    #include<bits/stdc++.h>using namespace std;typedef long long ll;#define fi first#define se second#define int long longconst ll mod=998244353;const int N=2e5+1;int n;int d[N];queue<int>q;vector<int>adj[N];int g[N],h[N],z;bool use[N];vector<int>ans[N];vector<int>f[N];bool vis[N];void dfs(int id,int p){vis[id]=true;for(auto c:adj[id]){if(c==p || d[c]!=d[id]) continue;dfs(c,id);for(int i=1; i<=z ;i++){ans[id][i]=min(ans[id][i],ans[c][i]+1);}ans[id][h[d[id]]]=0;}}void dfs2(int id,int p){for(auto c:adj[id]){if(c==p || d[c]!=d[id]) continue;for(int i=1; i<=z ;i++){ans[c][i]=min(ans[c][i],ans[id][i]+1);}ans[c][h[d[c]]]=0;dfs2(c,id);}}main(){ios::sync_with_stdio(false);cin.tie(0);cin >> n;for(int i=1; i<=n ;i++){int x;cin >> x;if(x==1) {q.push(i);d[i] = 0;}else d[i]=-1;     }for(int i=1; i<n ;i++){int u,v;cin >> u >> v;adj[u].push_back(v);adj[v].push_back(u);}while(!q.empty()){int x=q.front();q.pop();for(auto c:adj[x]){if(d[c] == -1){d[c]=d[x]+1;q.push(c);}}}for(int i=1; i<=n ;i++){f[d[i]].push_back(i);for(auto c:adj[i]){if(d[c]==d[i] && c>i){use[d[i]]=true;}}}for(int i=0; i<=n ;i++){if(use[i]){g[++z]=i;h[i]=z;}}/*for(int i=1; i<=n ;i++){cout << d[i] << ' ';}cout << endl;*/for(int i=1; i<=n ;i++){ans[i].resize(z+1);}for(int j=0; j<=n ;j++){for(auto x:f[j]){for(int i=1; i<=z ;i++) ans[x][i]=1e9;for(auto c:adj[x]){if(d[c]==d[x]-1){for(int i=1; i<=z ;i++) ans[x][i]=min(ans[x][i],max((ll)0,ans[c][i]-1));}}}for(auto x:f[j]){if(!vis[x]){dfs(x,0);dfs2(x,0);}}/*for(auto x:f[j]){cout << x << ": ";for(int i=1; i<=z ;i++) cout << ans[x][i] << ' ';cout << '\n';}*/}for(int i=1; i<=n ;i++){int res=d[i];for(int j=1; j<=z ;j++){if(ans[i][j]==0) res=max(res,d[i]*2-g[j]);}cout << res << ' ';}cout << '\n';}

CF1654-G. Snowy Mountain(2900) GOOD相关推荐

  1. pytorch torchvision.datasets

    torchvision 库是服务于pytorch深度学习框架的,用来生成图片,视频数据集,和一些流行的模型类和预训练模型. torchvision.datasets 所有数据集都是 torch.uti ...

  2. MSCOCO数据集下载安装---image_caption

    -下载安装MSCOCO2015的image_caption数据集,下载方式 [linux] 具体步骤: 1.$ git clone https://github.com/pdollar/coco.gi ...

  3. PyTorch - torchvision - datasets

    所有的数据集都是torch.utils.data.Dataset的子类,即它们实现了__getitem__和__len__方法. 因此,它们都可以传递给torch.utils.data.DataLoa ...

  4. torchvision学习之torchvision.datasets

    torchvision包 包含了目前流行的数据集,模型结构和常用的图片转换工具 torchvision.datasets torchvision.datasets中包含了以下数据集 MNIST COC ...

  5. Desolate Era Book 1, Chapter 1

    Book 1 – The Ji Clan of Swallow Mountain 第一卷 燕山纪氏 Chapter 1 – The Land of the Dead 第一章 地府 "Walk ...

  6. 遥感相关专业英语词汇汇总

    对网络上英语专业词汇进行汇总整理,如下表: 序号 英语基础词汇 摄影测量与遥感专业英语词汇 英语基础词汇 英语基础词汇-生态环境与遥感 1 Absorbed photosynthetically ac ...

  7. AVA Actions Dataset 详解

    文章目录 0. 前言 1. AVA简介 1.1. 基本情况 1.2. 如何获取 1.3. 数据集构建过程 1.4. annotations 解析 2. SlowFast 2.1. 构建 `Ava` 对 ...

  8. AVA时空检测数据集下载—AVA_ActionsAVA_Kinetics

    AVA_Actions&AVA_Kinetics AVA系列 AVA-Actions AVA-Kinetics AVA标注规范 标签类别 标注方式 CSV格式 旧版 视频下载 AVA-Acti ...

  9. SlowFast复现

    SlowFast复现 目录 参考 环境准备 配置slowfast环境 代码修改 测试 有可能出现的错误 目录 参考 论文 github地址 参考博客: [SlowFast复现]SlowFast Net ...

  10. 三分钟快速安装 facebookresearch SlowFast

    0 前言 去年写了一篇博客:[SlowFast复现]SlowFast Networks for Video Recognition复现代码 使用自己的视频进行demo检测 facebookresear ...

最新文章

  1. APL开发日志 -- 2013-03-02
  2. MySQL中的Text类型
  3. 穷不可怕,可怕的是“穷人思维”
  4. Delphi编程注意事项
  5. cookie 跨域问题
  6. YbtOJ#532-往事之树【广义SAM,线段树合并】
  7. jpa配置映射包_JPA – Hibernate –包级别的类型映射
  8. TCP第四次挥手为什么要等待2MSL
  9. jquery-加入购物车动画
  10. python 特殊方法(dunder-getitem)
  11. 无限复活服务器,绝地求生无限复活模式怎么玩 无限复活玩法说明介绍
  12. python 基本数据结构 ndarray
  13. python 干什么工作具有明显优势-Python到底能做什么?它的优点在哪
  14. Qt QLabel无法显示符号
  15. android变化HOLO对话风格
  16. 音视频从入门到精通——视频 码率 帧率 分辨率
  17. thinkphp5.1接入银联支付
  18. 神经网络自动布局技术,神经网络自动布局原理
  19. hdmi怎么支持2k分辨率_为什么显示器闪瞎眼 HDMI线版本有讲究
  20. 转载 gro转lammps

热门文章

  1. essay--网页播放器代码大全
  2. jQuery教程大纲
  3. 怎么彻底删除users下的文件夹_什么工具可以有效清理C:\Users\用户名\AppData目录下的文件?...
  4. java-php-python-ssm智能健身房管理计算机毕业设计
  5. 好消息!iPhone 4, 3GS, 3G 基带 5.14.02 和 2.10.4 已经软解
  6. PADS如何导入DXF文件
  7. 使用Hex view编写脚本生成特定格式刷写文件
  8. 沈善增谈学太极的经历
  9. 兼容iOS10 的一些整理
  10. oracle 修改pkg命令,Oracle PKG创造