BZOJ 1912: [Apio2010]patrol 巡逻 (树的直径)(详解)
题目:
https://www.lydsy.com/JudgeOnline/problem.php?id=1912
题解:
首先,显然当不加边的时候,遍历一棵树每条边都要经过两次。那么现在考虑k==1的情况,考虑加入的这一条边有什么作用。
显然,如图4边的作用就是使得原来的1-2-3-3-2-1路线变为了4-3-2-1或1-2-3-4,那么作用就是以多走一步的代价使得这条新边两端的两个结点的遍历路径长度减半。
因此,想要使路径最短,就要使这条新边两端的两个结点之间的距离更长,显然,当两端的结点在原树中的路径为原树的直径时取得k==1时的最优解。设直径长度为dis,则k==1时ans=(n-1)*2-dis+1。
那么,k==2的时候怎么办呢。显然直接求次长链的做法是错的,因为求次长链的时候会与直径的某些边重复,那么这些边就是没有意义的,答案显然不更优。
因此,我们采用另一种方法:将直径上的边权全部置成-1,然后再跑一遍最长链。开始我也很不懂为什么要置成-1而不置成0,欸还是上面那张图是因为你考虑当你通过4边走到最下面那个点之后,显然你还是要回到最初的点的,而如果路径上的边与之前的直径重复,那么等于说你多加了一遍这条边,因此置成-1后不就相当于没加吗
P.S.当边权有负数时求直径不能用两边dfs,而应该用dp。WA了好久qwq。。。于是我第一遍求直径时用的两边dfs,第二遍用的dp。。。
代码:
#include<bits/stdc++.h> using namespace std; const int maxn=;
int dep[maxn],fa[maxn],head[maxn],cnt=,root,ans,n,k,mdep[maxn],maxx; struct ed{
int next,to,w;
}e[maxn<<]; void add(int u,int v){
e[++cnt]=(ed){head[u],v,},head[u]=cnt;
e[++cnt]=(ed){head[v],u,},head[v]=cnt;
} void dfs(int now,int f){
fa[now]=f;mdep[now]=;
for(int i=head[now];i;i=e[i].next){
int tt=e[i].to;
if(tt==f) continue;
dep[tt]=dep[now]+e[i].w;
dfs(tt,now); mdep[now]=max(mdep[now],mdep[tt]+e[i].w);
}
} void dp(int now,int f){
int fm=-,sm=-;
for(int i=head[now];i;i=e[i].next){
int tt=e[i].to;
if(tt==f) continue;
if(mdep[tt]+e[i].w>sm){
if(mdep[tt]+e[i].w>fm)
swap(fm,sm),fm=mdep[tt]+e[i].w;
else
sm=mdep[tt]+e[i].w;
}
dp(tt,now);
}
maxx=max(maxx,fm+sm);
maxx=max(maxx,fm);
maxx=max(maxx,sm);
} int main(){
scanf("%d%d",&n,&k);
int u,v;
for(int i=;i<n;i++)
scanf("%d%d",&u,&v),add(u,v);
dfs(,);root=;
for(int i=;i<=n;i++)
if(dep[i]>dep[root])
root=i;
dep[root]=,dfs(root,);
for(int i=;i<=n;i++)
if(dep[i]>dep[root])
root=i;
ans=(n-)*-dep[root]+;
if(k==){
while(fa[root])
for(int i=head[root];i;i=e[i].next){
int tt=e[i].to;
if(tt==fa[root]){
e[i].w=e[i^].w=-;
root=fa[root];break;
}
}
dep[]=;maxx=-0x3f3f3f3f;
dfs(,);dp(,);
ans-=maxx-;
}
printf("%d",ans);
return ;
}
BZOJ 1912: [Apio2010]patrol 巡逻 (树的直径)(详解)的更多相关文章
- bzoj 1912 : [Apio2010]patrol 巡逻 树的直径
题目链接 如果k==1, 显然就是直径. k==2的时候, 把直径的边权变为-1, 然后在求一次直径. 变为-1是因为如果在走一次这条边, 答案会增加1. 学到了新的求直径的方法... #includ ...
- bzoj 1912: [Apio2010]patrol 巡逻【不是dp是枚举+堆】
我是智障系列.用了及其麻烦的方法= =其实树形sp就能解决 设直径长度+1为len(环长) 首先k=1,直接连直径两端就好,答案是2*n-len 然后对于k=2,正常人的做法是树形dp:先求直径,然后 ...
- bzoj 1912: [Apio2010]patrol 巡逻
呵呵呵呵呵呵,自己画图,大概半个小时,觉的连上边会成环(是不是该交仙人掌了??)然后求环不重合部分最大就好了, 结果写了一坨DP,最后写不下去了,再次扒了题解. 发现我真的是个sb. k==1,直接是 ...
- 【BZOJ-1912】patrol巡逻 树的直径 + DFS(树形DP)
1912: [Apio2010]patrol 巡逻 Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 1034 Solved: 562[Submit][St ...
- 【BZOJ】1912: [Apio2010]patrol 巡逻(树的直径)
题目 传送门:QWQ 分析 $ k=1 $ 时显然就是树的直径 $ k=2 $ 时怎么做呢? 做法是把一开始树的直径上的边的边权改成$ -1 $,那么当我们第二次用这些边做环时就抵消了一开始的贡献. ...
- BZOJ 1912:[Apio2010]patrol 巡逻(树直径)
1912: [Apio2010]patrol 巡逻 Input 第一行包含两个整数 n, K(1 ≤ K ≤ 2).接下来 n – 1行,每行两个整数 a, b, 表示村庄a与b之间有一条道路(1 ≤ ...
- [Apio2010]patrol 巡逻
1912: [Apio2010]patrol 巡逻 Time Limit: 4 Sec Memory Limit: 64 MBSubmit: 2541 Solved: 1288[Submit][S ...
- 【BZOJ1912】[Apio2010]patrol 巡逻 树形DP
[BZOJ1912][Apio2010]patrol 巡逻 Description Input 第一行包含两个整数 n, K(1 ≤ K ≤ 2).接下来 n – 1行,每行两个整数 a, b, 表示 ...
- AVL树平衡旋转详解
AVL树平衡旋转详解 概述 AVL树又叫做平衡二叉树.前言部分我也有说到,AVL树的前提是二叉排序树(BST或叫做二叉查找树).由于在生成BST树的过程中可能会出现线型树结构,比如插入的顺序是:1, ...
随机推荐
- CIFS 与 SMB 有什么区别?
CIFS 与 SMB 有什么区别? https://www.getnas.com/2018/11/30/cifs-vs-smb/ 网络协议 一知半解 学习一下挺好的.. 记得 win2019 已经废弃 ...
- Linux(CentOS7)命令学习摘要
1. 修改机器名 hostnamectl set-hostname newname 2. hosts主机存放位置 /etc/hosts 3. 安装tigervncserver, 然后使用vncserv ...
- JSON Support in PostgreSQL and Entity Framework
JSON 和JSONB的区别(What's difference between JSON and JSONB data type in PosgresSQL?) When should be use ...
- k8s使用glusterfs做存储
一.安装glusterfs https://www.cnblogs.com/zhangb8042/p/7801181.html 环境介绍; centos 7 [root@k8s-m ~]# cat / ...
- SQL Server2012中如何通过bak文件还原SQL Server2012数据库
1 登陆完数据库后,不要新建数据库,直接点击“数据库”然后右击"还原数据库". 2 在"源"选项中选择"设备". 3 选择相应的bak文件并 ...
- Chrome 75 & lazy-loading
Chrome 75 & lazy-loading https://addyosmani.com/blog/lazy-loading/ https://chromestatus.com/feat ...
- BZOJ2219数论之神——BSGS+中国剩余定理+原根与指标+欧拉定理+exgcd
题目描述 在ACM_DIY群中,有一位叫做“傻崽”的同学由于在数论方面造诣很高,被称为数轮之神!对于任何数论问题,他都能瞬间秒杀!一天他在群里面问了一个神题: 对于给定的3个非负整数 A,B,K 求出 ...
- Typecho——简介及安装
Typecho Typecho是由type和echo两个词合成的,来自于开发团队的头脑风暴.Typecho基于PHP5开发,支持多种数据库,是一款内核强健﹑扩展方便﹑体验友好﹑运行流畅的轻量级开源博客 ...
- 「AC自动机」学习笔记
AC自动机(Aho-Corasick Automaton),虽然不能够帮你自动AC,但是真的还是非常神奇的一个数据结构.AC自动机用来处理多模式串匹配问题,可以看做是KMP(单模式串匹配问题)的升级版 ...
- Mining Station on the Sea HDU - 2448(费用流 || 最短路 && hc)
Mining Station on the Sea Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Jav ...