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, ...
随机推荐
- Oracle 不小心删除undo数据文件以及磁盘空间不足导致不能登录的解决办法
在一次测试中,由于导入的数据量过大导致事务一直提交失败因为磁盘空间不够用了,一检查发现是undo表空间不够用,于是重新创建了一个表空间,准备把之前的undo表空间删除,删除时却发现一直删不掉,因为它一 ...
- java lang(ClassLoader)
一.什么是ClassLoader? 大家都知道,当我们写好一个Java程序之后,不是管是CS还是BS应用,都是由若干个.class文件组织而成的一个完整的Java应用程序,当程序在运行时,即会调用该程 ...
- SpringBoot 中 JPA 的使用
详细连接 简书https://www.jianshu.com/p/c14640b63653 新建项目,增加依赖 在 Intellij IDEA 里面新建一个空的 SpringBoot 项目.具体步骤参 ...
- SOAP-ERROR: Encoding: string … is not a valid utf-8 string
今天遇到一个错误,看标题就知道是什么错误了.... 最坑爹的是,不是所有的用户会报这个错误.只有少部分.在生产环境又没办法调试. 找了半天都不知道什么原因,字面意思大概是需要一个utf8编码的字符串, ...
- 从 Aliyun 经典网络迁移到 Aliyun VPC 网络
由于阿里云策略问题,要求用户从经典网络中全部迁出,搬迁到他们设置的 VPC 网络中.这里的 VPC 大概指的是逻辑上的一个虚拟局域网.即使是实际上你的机器垮机房在阿里云的不同机房.但是他们仍然能从逻辑 ...
- JSTL 之 <c:out>
jstl的<c:out value="${hello}"></c:out> EL表达式的${hello },两者一般没什么不同,但是EL表达式输出的时候回尝 ...
- css背景色 透明字体不透明
.demo{ padding: 25px; background-color: rgba(,,,0.5);/* IE9.标准浏览器.IE6和部分IE7内核的浏览器(如QQ浏览器)会读懂 */ }
- Siki的虚幻第一季
空项目.一闪而过的解决方法 命名空间std::cout的作用: int ,long , long long类型的范围 unsigned int 0-4294967295 int 21474 ...
- Spring 使用介绍(三)—— 资源
一.Resource接口 Spring提供Resource接口,代表底层外部资源,提供对底层外部资源的一致性访问接口 public interface InputStreamSource { Inpu ...
- 蒟阵P3390 【模板】矩阵快速幂
代码如下: #include<iostream> #include<cstdio> #include<cstdlib> #include<cmath> ...