如果考虑不算上新修的道路,那么答案显然为\(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. 谈谈HTTP协议中的短轮询、长轮询、长连接和短连接

    引言 最近刚到公司不到一个月,正处于熟悉项目和源码的阶段,因此最近经常会看一些源码.在研究一个项目的时候,源码里面用到了HTTP的长轮询.由于之前没太接触过,因此LZ便趁着这个机会,好好了解了一下HT ...

  2. rtmp_specification_1.0

    Copyright Adobe Systems Incorporated H. Parmar, Ed. M. Thornburgh, Ed. Adobe December 21, 2012 Adobe ...

  3. RabbitMQ 从入门到精通 (一)

    目录 1. 初识RabbitMQ 2. AMQP 3.RabbitMQ的极速入门 4. Exchange(交换机)详解 4.1 Direct Exchange 4.2 Topic Exchange 4 ...

  4. kafka高吞吐量的分布式发布订阅的消息队列系统

    一:kafka介绍kafka(官网地址:http://kafka.apache.org)是一种高吞吐量的分布式发布订阅的消息队列系统,具有高性能和高吞吐率. 1.1 术语介绍BrokerKafka集群 ...

  5. POJ 3624 Charm Bracelet(01背包模板题)

    题目链接 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 52318   Accepted: 21912 Descriptio ...

  6. strace调试工具编译移植

     源码下载:https://github.com/strace/strace/releases/tag/v4.18(使用的较老版本,最新版 5.4 编译时依赖较多,最终博主放弃使用) [ 编译步骤 ] ...

  7. Linux下使用matlab在后台默默的运行.m文件(无界面形式)

    Linux下使用matlab在后台默默的运行.m文件(无界面形式)本主在Ubuntu18.04LTS上已经安装了matlab直接运行Matlab$ matlab会启动 matlab,出现启动界面但想要 ...

  8. 长乐国庆集训Day5-2

    T1 彩虹 题目 [题目描述] Mr.Raju和他的一个大家庭外出度假,他们想要乘着彩虹欣赏周围的景色,但是这样最会有一些问题. 在他们家族中,如果一个人想要骑上彩虹,那么他喜欢的所有人和喜欢他的所有 ...

  9. linux redis 安装和密码设置

    1.下载redis wget http://download.redis.io/releases/redis-4.0.8.tar.gz 2.解压 tar xzvf redis-4.0.8.tar.gz ...

  10. Netty源码分析之NioEventLoop(三)—NioEventLoop的执行

    前面两篇文章Netty源码分析之NioEventLoop(一)—NioEventLoop的创建与Netty源码分析之NioEventLoop(二)—NioEventLoop的启动中我们对NioEven ...