如果考虑不算上新修的道路,那么答案显然为\(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. 使用mwget代替wget

    wget相对于浏览器来说,速度会比较偏慢,特别是国外的网站. 刚好经常用的xftp无法正常使用了,于是开始折腾mwget 下面来看一下安装步骤: wget http://jaist.dl.source ...

  2. cube-slide组件的应用

    <template> <div> <cube-slide :data="items"/> </div> </template& ...

  3. pom中parent和dependency区别以及dependencyManagement区别

    真的很详细 很感动 1.在同一个pom文件下,如果<dependencies>和<dependencyManagement>中都对该jar做了依赖,以<dependenc ...

  4. Git 删除所有历史提交记录方法

    Git 删除所有历史提交记录方法 切换分支 git checkout --orphan latest_branch 添加所有文件 git add -A 提交更改 git commit -am &quo ...

  5. MySQL8 全部数据类型

    数字类型 日期类型 字符串类型 CHAR和VARCHAR 表列数和行大小限制 MySQL每个表的硬限制为4096列,但对于给定的表,有效最大值可能更小.确切的列限制取决于几个因素: 表的最大行大小限制 ...

  6. 袁新生《LINGO和Excel在数学建模中的应用》

    内容介绍 本书深入浅出地介绍了LINGO的基础知识.用LINGO语言描述现实问题的方法和用Excel处理数据的方法,重点是这两种软件在解决各种优化问题以及在数学建模中的应用,通过丰富的实例介绍了把实际 ...

  7. 10步成为一个优秀的Java开发!

    1.拥有坚实的基础并理解面向对象原则 Java开发人员必须深刻理解面向对象编程.如果没有面向对象编程的坚实基础,就无法感受到像Java这样的面向对象编程语言的美感. 如果你不太了解现象对象编程是什么, ...

  8. Java基础---Java环境配置

    java 下载:https://www.java.com/zh_CN/ 1.Java安装:jdk9 2. JAVA_HOME 环境变量的配置 在DOS命令行下使用这些工具,就要先进入到JDK的bin目 ...

  9. flask源码系列

    更新中 HTML文档中元素存在,但是在浏览器中不显示.一般用于配合JavaScript代码使用. 04 LocalStack和Local对象实现栈的管理 05 Flask源码之:配置加载 06 Fla ...

  10. 选择类排序 (简单选择排序,堆排序)— c语言实现

    选择类排序包括: (1)  简单选择排序 (2)树形选择排序 (3)堆排序 简单选择排序: [算法思想]:在第 i 趟简单选择排序中,从第 i 个记录开始,通过 n - i 次关键字比较,从 n - ...