如果考虑不算上新修的道路,那么答案显然为\(2*(n-1)\)。

考虑\(k=1\)的情况,会发现如果我们新修建一个道路,那么就会有一段路程少走一遍。这时选择连接树的直径的两个端点显然是最优的。

难就难在\(k=2\)的时候,还是上面的思路,首先肯定连接两个叶子结点最优。假设我们连接的是\(x,y\)两个叶子结点,它们到直径的距离分别为\(dis[x],dis[y]\),并设直径上两点的距离为\(d[u,v]\),这里\(u,v\)分别为叶子结点所在链和直径的交点。

因此最后的答案会增加\(d[u,v]-dis[x]-dis[y]\)。要使答案最小,那么也就也是使得\(dis[x]+dis[y]-d[u,v]\)最大。脑补一下,就会发现这其实就是在所有直径上面的边权取反过后,树的最长链。

所以再求一次树的直径就好了。因为最后有负边权存在,通过\(dfs/bfs\)来求会出错。所以最后dp一次就好啦。

代码如下:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 5;
int n, k;
struct Edge{
int u, v, next, w;
}e[N << 1];
int head[N], tot;
void adde(int u, int v) {
e[tot].w = 1; e[tot].v = v; e[tot].next = head[u]; head[u] = tot++;
}
int vis[N], f[N], d[N], dp[N];
void dfs(int u, int fa) {
f[u] = fa;
for(int i = head[u]; i != -1; i = e[i].next) {
int v = e[i].v;
if(v != fa) {
d[v] = d[u] + e[i].w;
dfs(v, u) ;
}
}
}
int mx, p, L;
void Get(int x) {
d[x] = mx = 0;
dfs(x, 0);
for(int i = 1; i <= n; i++)
if(d[i] > mx) mx = d[i], p = i;
}
int solve() {
Get(1);Get(p);
return mx;
}
void dfs2(int u, int fa) {
vis[u] = 1;
for(int i = head[u]; i != -1; i = e[i].next) {
int v = e[i].v;
if(v == fa || !vis[v]) continue ;
e[i].w = e[i ^ 1].w = -1;
dfs2(v, u) ;
}
}
void Dp(int u, int fa) {
for(int i = head[u]; i != -1; i = e[i].next) {
int v = e[i].v;
if(v == fa) continue ;
Dp(v, u);
L = max(L, dp[u] + dp[v] + e[i].w) ;
dp[u] = max(dp[u], dp[v] + e[i].w) ;
}
}
int main() {
ios::sync_with_stdio(false); cin.tie(0);
cin >> n >> k;
memset(head, -1, sizeof(head)) ;
for(int i = 1; i < n; i++) {
int u, v;
cin >> u >> v;
adde(u, v); adde(v, u);
}
int l = solve() ;
int ans = 2 * (n - 1) - l + 1;
if(k == 2) {
int u = p;
while(u != 0) {
vis[u] = 1;
u = f[u];
}
dfs2(p, 0) ;
Dp(1, 0) ;
ans = ans - L + 1;
}
cout << ans ;
return 0;
}

洛谷P3629 [APIO2010]巡逻(树的直径)的更多相关文章

  1. 洛谷 P3629 [APIO2010]巡逻 解题报告

    P3629 [APIO2010]巡逻 题目描述 在一个地区中有 n 个村庄,编号为 1, 2, ..., n.有 n – 1 条道路连接着这些村 庄,每条道路刚好连接两个村庄,从任何一个村庄,都可以通 ...

  2. [洛谷P3629] [APIO2010]巡逻

    洛谷题目链接:[APIO2010]巡逻 题目描述 在一个地区中有 n 个村庄,编号为 1, 2, ..., n.有 n – 1 条道路连接着这些村 庄,每条道路刚好连接两个村庄,从任何一个村庄,都可以 ...

  3. 洛谷 P3629 [APIO2010]巡逻

    题目在这里 这是一个紫题,当然很难. 我们往简单的想,不建立新的道路时,从1号节点出发,把整棵树上的每条边遍历至少一次,再回到1号节点,会恰好经过每条边两次,路线总长度为$2(n-1)$,根据树的深度 ...

  4. BZOJ1912或洛谷3629 [APIO2010]巡逻

    一道树的直径 BZOJ原题链接 洛谷原题链接 显然在原图上路线的总长为\(2(n-1)\). 添加第一条边时,显然会形成一个环,而这条环上的所有边全部只需要走一遍.所以为了使添加的边的贡献最大化,我们 ...

  5. 洛谷P3373 [模板]线段树 2(区间增减.乘 区间求和)

    To 洛谷.3373 [模板]线段树2 题目描述 如题,已知一个数列,你需要进行下面两种操作: 1.将某区间每一个数加上x 2.将某区间每一个数乘上x 3.求出某区间每一个数的和 输入输出格式 输入格 ...

  6. 【BZOJ2830/洛谷3830】随机树(动态规划)

    [BZOJ2830/洛谷3830]随机树(动态规划) 题面 洛谷 题解 先考虑第一问. 第一问的答案显然就是所有情况下所有点的深度的平均数. 考虑新加入的两个点,一定会删去某个叶子,然后新加入两个深度 ...

  7. 【洛谷 P3629】 [APIO2010]巡逻 (树的直径)

    题目链接 容易发现,当加一条边时,树上会形成一个环,这个环上的每个点都是只要走一次的,也就是说我们的答案减少了这个环上点的个数,要使答案最小,即要使环上的点最多,求出直径\(L\),则答案为\(2(n ...

  8. 树的直径初探+Luogu P3629 [APIO2010]巡逻【树的直径】By cellur925

    题目传送门 我们先来介绍一个概念:树的直径. 树的直径:树中最远的两个节点间的距离.(树的最长链)树的直径有两种方法,都是$O(N)$. 第一种:两遍bfs/dfs(这里写的是两遍bfs) 从任意一个 ...

  9. 洛谷 [P3629] 巡逻

    树的直径 树的直径有两种求法 1.两遍 dfs 法, 便于输出具体方案,但是无法处理负权边 2.DP 法,代码量少,可以处理负权边 #include <iostream> #include ...

随机推荐

  1. Jmeter做压力测试

    1)首先双击bin/jmeter.bat 2)创建Thread Group 3)配置HTTP Request 4)配置Aggregate Report 5)配置并发数和并发时间 6)点击绿色按钮,执行 ...

  2. 【ML基础】皮尔森相关系数(Pearson correlation coefficient)

    前言 参考 1. 皮尔森相关系数(Pearson correlation coefficient): 完

  3. 【计算机视觉基础】IPM

    IPM code #if 0 void xyp2ipmp(cv::Mat& xyp, cv::Mat& ipmp, cv::Mat& xylim, Size& sz){ ...

  4. vs code 自定义配置记录

    java环境安装:https://devblogs.microsoft.com/visualstudio/announcing-visual-studio-code-java-installer/ 保 ...

  5. 关于Django数据库mysql连接错误问题Connection to api@localhost failed. [08001] Could not create connection to d

    Connection to api@localhost failed. [08001] Could not create connection to d 错误类型 django连接mysql数据库错误 ...

  6. linux安装 uwsgi 测试 test.py 不显示hello world 的解决办法

    一般部署项目到服务器,会安装uwsgi,但是很多教程在安装它的时候会让你测试一下安装好了没,于是就有很多像我一样懵逼的少年掉进一个坑里出不来,很久.很久... 那就是最后浏览器输入ip:8000端口后 ...

  7. *** WARNING L16: UNCALLED SEGMENT, IGNORED FOR OVERLAY PROCESS

    Warning提示的原因是 一些未使用的函数被编译进入芯片,浪费了RAM/ROM. 解决的方法: 1.将不用的函数注释: 2.在未使用函数的首尾加条件编译 #ifdef 函数名 和 #endif ,不 ...

  8. java之mybatis整合spring

    这篇讲解spring+mybatis的整合. 目录结构: 一. 整合spring的第一种方法 1. 新建 java 项目 : spring_mybatis 2.导入jar 包-----spring和m ...

  9. C# vb .net实现移除像素特效滤镜

    在.net中,如何简单快捷地实现Photoshop滤镜组中的移除像素特效呢?答案是调用SharpImage!专业图像特效滤镜和合成类库.下面开始演示关键代码,您也可以在文末下载全部源码: 设置授权 第 ...

  10. P1349 广义斐波那契数列(矩阵乘法)

    题目 P1349 广义斐波那契数列 解析 把普通的矩阵乘法求斐波那契数列改一改,随便一推就出来了 \[\begin{bmatrix}f_2\\f_1 \end{bmatrix}\begin{bmatr ...