[Apio2010]patrol 巡逻
1912: [Apio2010]patrol 巡逻
Time Limit: 4 Sec Memory Limit: 64 MB
Submit: 2541 Solved: 1288
[Submit][Status][Discuss]
Description
Input
表示村庄a与b之间有一条道路(1 ≤ a, b ≤ n)。
Output
Sample Input
1 2
3 1
3 4
5 3
7 5
8 5
5 6
Sample Output
HINT
10%的数据中,n ≤ 1000, K = 1;
30%的数据中,K = 1;
80%的数据中,每个村庄相邻的村庄数不超过 25;
90%的数据中,每个村庄相邻的村庄数不超过 150;
100%的数据中,3 ≤ n ≤ 100,000, 1 ≤ K ≤ 2。
Source
[Submit][Status][Discuss]
HOME
Back
题解
参照AntiQuality的题解。
k=0
不过首先挖掘性质:显然的是,若只是树形图,路径最短为2n−2;并且实际上起点任意对于答案来说都是一样的
k=1
然后我们来想一想k=1的情况。比如现在我们有一颗树长成这样:

然后我们现在添加一条边:

可以发现形成的环上,若环长度为lens,那么需要经过的路径就从2∗lens变为了lens+1。并且对于其他节点来说,它们的花费是不改变的。
由此自然想到我们将最长链的首尾相连,就可以得到k=1时的答案。
k=2
有了k=1,扩展至k=2的思路大致相同。除了最长链形成的环,我们需要在树上另找一条次长链。
这里有一个技巧就是把最长链上的边权全都改为-1
如果我们什么处理都没有,直接求一个次长链(次短路方法), 可能会和最长链重合,那么最长链上的一部分就会走两遍
所以我们在求出最长链之后,把最长链上的边权赋为-1, 这样再跑一个裸的直径就好了 (这样就可以保证可以在新求出的直径中尽量少重合原先的直径)
时间复杂度\(O(n)\)
#include<bits/stdc++.h>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
rg T data=0,w=1;rg char ch=getchar();
for(;!isdigit(ch);ch=getchar())if(ch=='-') w=-w;
for(;isdigit(ch);ch=getchar()) data=data*10+ch-'0';
return data*w;
}
template<class T>il T read(rg T&x) {return x=read<T>();}
typedef long long ll;
using namespace std;
co int N=1e5+6;
int n,k,d[N],fa[N];
int Head[N],Edge[N*2],Leng[N*2],Next[N*2],tot=1;
bool v[N];
void add(int x,int y,int z){
Edge[++tot]=y,Leng[tot]=z,Next[tot]=Head[x],Head[x]=tot;
}
void dfs(int x,int&t){
v[x]=1;
for(int i=Head[x],y;i;i=Next[i]){
if(v[y=Edge[i]]) continue;
if((d[y]=d[x]+Leng[i])>=d[t]) t=y;
fa[y]=i;
dfs(y,t);
}
v[x]=0;
}
void dp(int x,int&t){
v[x]=1;
for(int i=Head[x],y;i;i=Next[i]){
if(v[y=Edge[i]]) continue;
dp(y,t);
t=max(t,d[x]+d[y]+Leng[i]);
d[x]=max(d[x],d[y]+Leng[i]);
}
v[x]=0;
}
int main(){
read(n),read(k);
for(int i=1,x,y;i<n;++i){
read(x),read(y);
add(x,y,1),add(y,x,1);
}
int t=1;
dfs(1,t);
d[t]=fa[t]=0;
int tt=t;
dfs(t,tt);
int ans=2*(n-1)-(d[tt]-1);
if(k==2){
while(fa[tt]){
Leng[fa[tt]]=Leng[fa[tt]^1]=-1;
tt=Edge[fa[tt]^1];
}
tt=0;
memset(d,0,sizeof d);
dp(t,tt);
ans-=tt-1;
}
printf("%d\n",ans);
return 0;
}
[Apio2010]patrol 巡逻的更多相关文章
- 【BZOJ1912】[Apio2010]patrol 巡逻 树形DP
[BZOJ1912][Apio2010]patrol 巡逻 Description Input 第一行包含两个整数 n, K(1 ≤ K ≤ 2).接下来 n – 1行,每行两个整数 a, b, 表示 ...
- BZOJ 1912:[Apio2010]patrol 巡逻(树直径)
1912: [Apio2010]patrol 巡逻 Input 第一行包含两个整数 n, K(1 ≤ K ≤ 2).接下来 n – 1行,每行两个整数 a, b, 表示村庄a与b之间有一条道路(1 ≤ ...
- BZOJ1912 [Apio2010]patrol 巡逻
本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转 ...
- 【树形dp 最长链】bzoj1912: [Apio2010]patrol 巡逻
富有思维性的树形dp Description Input 第一行包含两个整数 n, K(1 ≤ K ≤ 2).接下来 n – 1行,每行两个整数 a, b, 表示村庄a与b之间有一条道路(1 ≤ a, ...
- BZOJ1912:[APIO2010]patrol巡逻
Description Input 第一行包含两个整数 n, K(1 ≤ K ≤ 2).接下来 n – 1行,每行两个整数 a, b, 表示村庄a与b之间有一条道路(1 ≤ a, b ≤ n). Ou ...
- 【bzoj1912】 Apio2010—patrol 巡逻
http://www.lydsy.com/JudgeOnline/problem.php?id=1912 (题目链接) 题意 给出一棵树,要求在树上添加K(1 or 2)条边,添加的边必须经过一次,使 ...
- P1912: [Apio2010]patrol 巡逻
这道题讨论了好久,一直想不明白,如果按传统的随便某一个点出发找最长链,再回头,K=2 的时候赋了-1就没法用这种方法找最长链了,于是乎,更强的找最长链的方法就来了..类似于DP的东西吧.先上代码: ; ...
- bzoj 1912 : [Apio2010]patrol 巡逻 树的直径
题目链接 如果k==1, 显然就是直径. k==2的时候, 把直径的边权变为-1, 然后在求一次直径. 变为-1是因为如果在走一次这条边, 答案会增加1. 学到了新的求直径的方法... #includ ...
- BZOJ 1912: [Apio2010]patrol 巡逻 (树的直径)(详解)
题目: https://www.lydsy.com/JudgeOnline/problem.php?id=1912 题解: 首先,显然当不加边的时候,遍历一棵树每条边都要经过两次.那么现在考虑k==1 ...
随机推荐
- 第07组 Beta冲刺(2/4)
队名:秃头小队 组长博客 作业博客 组长徐俊杰 过去两天完成的任务:学习了很多东西 Github签入记录 接下来的计划:继续学习 还剩下哪些任务:后端部分 燃尽图 遇到的困难:自己太菜了 收获和疑问: ...
- 转载:c++获取本机IP地址
windows下获取IP地址的两种方法: 一种可以获取IPv4和IPv6,但是需要WSAStartup: 一种只能取到IPv4,但是不需要WSAStartup: 如下: 方法一:(可以获取IPv4和I ...
- Centos 安装mysql8
Centos 安装mysql ,转载 https://www.cnblogs.com/funbin/p/11154784.html 1.下载mysql wget -i -c https://repo. ...
- HTML-点击Div读取本地文件内容
<!DOCTYPE html> <html> <div id="container" onclick="choosefile();" ...
- 3.NioEventLoop的启动和执行
NioEventLoop启动和执行 NioEventLoop启动 在服务端启动的代码中,我们看到netty在注册和绑定时,判断了当前线程是否是NioEventLoop线程.如果不是, 则将这些操作包装 ...
- java之hibernate之基于主键的双向一对一关联映射
这篇 基于主键的双向一对一关联映射 1.依然考察人和身份证的一对一关系,如果采用主键关联,那么其表结构为: 2.类结构 Person.java public class Person implemen ...
- ② Python3.0 运算符
Python3.0 语言支持的运算符有: 算术运算符.比较(关系)运算符.赋值运算符.逻辑运算符.位运算符.成员运算符.身份运算符.运算符优先级 一.算术运算符 常见的算术运算符有+,-,*,/,%, ...
- z7z8记录
http://www.ypppt.com/ ppt模板地址
- React Native 开发豆瓣评分(六)添加字体图标
添加依赖 yarn add react-native-vector-icons Link 依赖 react-native link react-native-vector-icons 使用默认字体图标 ...
- ORM 对表操作 详解
目录 ORM对表操作详解 表结构 ORM对表的 增 删 改 查 基于对象的跨表查询 -- 类似于子查询 基于双下划的跨表查询 -- 连表 join ORM对表的操作示例 正向查 与 反向查 relat ...