2020CCPC(秦皇岛) - Kingdom‘s Power(树形dp+贪心)
题目大意:给出一棵 n 个节点的有根树,点 1 为根节点,现在在根节点有无穷多个士兵,每一秒可以控制任意一个士兵向任意一个单位移动一步,士兵移动到的点会被永久占领,现在问最少需要经过多少秒,才能将所有的点都占领
题目分析:首先不难看出的两个小结论是:
- 如果所有的叶子节点都被占领,那么沿途的所有点也会被占领,所以问题转换为了到每个叶子节点的最短时间
- 第一步肯定是需要从根节点到其中一个叶子节点的,贪心去想,到深度最低的那个叶子节点一定是最优的
树形dp维护一下从根节点过来更优还是从相邻的叶子结点更优,然后更新答案即可,这里参考了网上的解法,形式参数维护一个变量表示到达当前节点时的最短距离,递归的返回值是自底向上的最短距离,也就是从相邻的叶子节点过来的距离,这个距离和深度取个最小值就是答案了
最后还有一点需要贪心去考虑,感觉这个就是本题的难点了,假设只有一个士兵,从根节点出发若想遍历整棵树的话,最短的路线一定是:对于每个子树而言,最长的链只遍历一次,其余的链都会被遍历两次
基于此,对于每个子树而言,我们只需要将其按照 最长链 进行排序即可,因为最后去遍历的话一定只需要走一遍
代码:
//#pragma GCC optimize(2)
//#pragma GCC optimize("Ofast","inline","-ffast-math")
//#pragma GCC target("avx,sse2,sse3,sse4,mmx")
#include<iostream>
#include<cstdio>
#include<string>
#include<ctime>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<stack>
#include<climits>
#include<queue>
#include<map>
#include<set>
#include<sstream>
#include<cassert>
#include<bitset>
#include<unordered_map>
using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=1e6+100;vector<pair<int,int>>node[N];int deep[N],val[N];int dfs1(int u,int dep)
{if(node[u].empty())return 1;deep[u]=dep;for(auto &it:node[u]){int v=it.second;it.first=max(it.first,dfs1(v,dep+1));}sort(node[u].begin(),node[u].end());return node[u].back().first+1;
}int dfs2(int u,int dis)//返回值为自底向上的最短距离,dis储存的是到达当前点的最短距离
{val[u]=dis;if(node[u].empty())return 1;int mmin=dis;//到当前节点的最近距离 for(auto it:node[u]){int v=it.second;mmin=min(deep[u],dfs2(v,mmin+1));}return mmin+1;
}int main()
{
#ifndef ONLINE_JUDGE
// freopen("data.in.txt","r",stdin);
// freopen("data.out.txt","w",stdout);
#endif
// ios::sync_with_stdio(false);int w;cin>>w;int kase=0;while(w--){int n;scanf("%d",&n);for(int i=1;i<=n;i++)node[i].clear();for(int i=2;i<=n;i++){int fa;scanf("%d",&fa);node[fa].push_back(make_pair(0,i));}dfs1(1,0);dfs2(1,0);LL ans=0;for(int i=1;i<=n;i++)if(node[i].empty())ans+=val[i];printf("Case #%d: %lld\n",++kase,ans);}return 0;
}
2020CCPC(秦皇岛) - Kingdom‘s Power(树形dp+贪心)相关推荐
- CodeForces - 1453E Dog Snacks(树形dp+贪心)
题目链接:点击查看 题目大意:给出一棵有根树,现在需要选择一个最小的 k 值,可以满足下列的 n 次操作: 起始时位于点 1(根节点) 每一步选择一个未被遍历的节点中,距离最近的,且必须满足此距离小于 ...
- The Lost House POJ - 2057(树形dp+贪心 (双线最优子结构问题))
思路 题意:有一只蜗牛爬上树睡着之后从树上掉下来,发现后面的"房子"却丢在了树上面, 现在这 只蜗牛要求寻找它的房子,它又得从树根开始爬起,现在要求一条路径使得其找到房子 所要爬行 ...
- A. Parsa‘s Humongous Tree(树形DP + 贪心)
Problem - 1528A - Codeforces 两个玩家正在玩一个游戏.他们有一个整数1,2,...,n的排列组合(排列组合是一个数组,其中从1到n的每个元素正好出现一次).这个排列组合没有 ...
- [Codeforces 814D] An overnight dance in discotheque 树形dp,贪心
题目链接 题解:这道题,首先可以发现,圆与圆关系只有内含与外离, 所以可以建立出一个树形结构, 每个圆的父亲是与这个圆半径相差最小且包含这个圆的圆, 这样,整个一张图形成了一个森林,可以将圆按半径排序 ...
- [POI2014]FAR-FarmCraft 树形DP + 贪心思想
(感觉洛谷上题面那一小段中文根本看不懂啊,好多条件都没讲,直接就是安装也要一个时间啊,,,明明不止啊!还好有百度翻译......) 题意:一棵树,一开始在1号节点(root),边权都为1,每个点有点权 ...
- 树形dp ---- gym101667 A(贪心 + 树形dp + 两个dp方程组维护)
题目链接 题目大意: 就是一棵5e35e35e3的树,可以选择一些点,放上基站,如果uuu上的基站价值为ddd,那么距离uuu小于等于ddd的点都会被覆盖,问使得整棵树被覆盖需要的最小价值. 解题思路 ...
- 牛客 - 树上求和(贪心+树形dp)
题目链接:点击查看 题目大意:给出一棵树,现在要求给每条边赋上 0 ~ n - 1 的值,且不重复,规定每条路径 ( u , v ) 的权值和为其简单路径上的边权之和,而整棵树的权值和为 所有简单路径 ...
- HDU - 5242 Game(树形dp+树链剖分/树上贪心+思维)
题目链接:点击查看 题目大意:给出一棵包含n个节点的树,每个节点都有一个权值,整棵树的根是点1,问从点1开始向下一直走到叶子节点,可以走k次,怎么样走权值和最大,每个节点被走过一次后权值会变为0 题目 ...
- Codeforces 835 F Roads in the Kingdom(树形dp)
F. Roads in the Kingdom(树形dp) 题意: 给一张n个点n条边的无向带权图 定义不便利度为所有点对最短距离中的最大值 求出删一条边之后,保证图还连通时不便利度的最小值 $n & ...
最新文章
- 如何用Python做Web开发?——Django环境配置
- 两小时搞定负载均衡51CTO技术沙龙现场视频2
- bzoj 4012: [HNOI2015]开店
- 文件不混淆_Android Studio配置反混淆
- latex的 多行注释_Latex图形注释的实现方法
- 光纤收发器的7大挑选技巧
- 信息学奥赛一本通 1194:移动路线 | OpenJudge NOI 2.6 2718:移动路线
- 边开车边唱K?特斯拉汽车卡拉OK功能即将推出
- 从“连接”到“交互”—阿里巴巴智能对话交互实践及思考
- 文件上传------c#
- js根据本地文件路径上传文件(流上传)
- vue执行mounted_vue mounted方法执行多次问题的解决方案
- 手机andriod 开发---android test的执行
- SpringCloud学习笔记(八)Gateway 网关
- Android实现简单账号密码登录
- 2019 Java 全栈工程师进阶路线图,一定要收藏
- 苹果小白笔记本_【电脑】外媒评选年度办公/学生笔记本榜单 快看有你需要的吗...
- 分割字符串的AfxExtractSubString函数
- python弹球小游戏程序设计_Python写的弹球小游戏
- 汇编二进制转换ascii_将二进制数字转换为ASCII数字| 8085微处理器