本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作。

本文作者:ljh2000
作者博客:http://www.cnblogs.com/ljh2000-jump/
转载请注明出处,侵权必究,保留最终解释权!

Description

Input

第一行包含两个整数 n, K(1 ≤ K ≤ 2)。接下来 n – 1行,每行两个整数 a, b, 表示村庄a与b之间有一条道路(1 ≤ a, b ≤ n)。

Output

输出一个整数,表示新建了K 条道路后能达到的最小巡逻距离。

Sample Input

8 1
1 2
3 1
3 4
5 3
7 5
8 5
5 6

Sample Output

11

HINT

10%的数据中,n ≤ 1000, K = 1; 
30%的数据中,K = 1; 
80%的数据中,每个村庄相邻的村庄数不超过 25; 
90%的数据中,每个村庄相邻的村庄数不超过 150; 
100%的数据中,3 ≤ n ≤ 100,000, 1 ≤ K ≤ 2。

 
 
正解:树形DP
解题报告:
  这题很有意思,我记得以前做过一道叫做巡访的题目,正好是k=1的情况,结果这道题叫巡逻XD
  考虑k=1的时候,我们的答案很容易想到就是2*(n-1)-最长链+1,因为如果能加一条边的话,因为我希望减少的尽可能多,那么我只需要把最长链的首尾接起来,就不需要来回走,加一就是加了这一条新加入的边。
  但是k=2的时候呢?首先还是往最长链上面思考。然而做k=1的时候已经用掉了一段,k=2的时候怎么知道和k=1不重叠呢?
  很简单,我们在做k=1之后把最长链上的边权全部修改为-1,再跑一遍最长链就可以了。可能有人会疑问,那-1的边又被选了那不是相当于还是选进去两次了吗?但是考虑第一次算这条边的时候加了一,第二次的时候加的是-1,相当于是这条边没有产生任何贡献。可以画一画图就会发现,相当于是把两条交错的链变成了两条分开的链。这个做法很优秀。
  所以最后的总复杂度就是O(n)。 
 //It is made by ljh2000
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <ctime>
#include <vector>
#include <queue>
#include <map>
#include <set>
using namespace std;
typedef long long LL;
const int inf = (<<);
const int MAXN = ;
const int MAXM = ;
int n,k,ecnt,next[MAXM],to[MAXM],w[MAXM];
int f[MAXN][],first[MAXN],g[MAXN],p[MAXN];
int ans,root,Ans,Son,Son2; inline int getint()
{
int w=,q=; char c=getchar();
while((c<'' || c>'') && c!='-') c=getchar(); if(c=='-') q=,c=getchar();
while (c>='' && c<='') w=w*+c-'', c=getchar(); return q ? -w : w;
}
inline void link(int x,int y){ next[++ecnt]=first[x]; first[x]=ecnt; to[ecnt]=y; w[ecnt]=; }
inline void dfs(int x,int fa){
int now,son=,son2=;
for(int i=first[x];i;i=next[i]) {
int v=to[i]; if(v==fa) continue; dfs(v,x); now=f[v][]+w[i];
if(now>f[x][]) son=g[x],son2=p[x],f[x][]=f[x][],f[x][]=now,g[x]=v,p[x]=i; else if(now>f[x][]) f[x][]=now,son=v,son2=i;
}
if(f[x][]+f[x][]>ans) { ans=f[x][]+f[x][]; root=x; Son=son; Son2=son2; }
} inline void work(){
n=getint(); k=getint(); int x,y; for(int i=;i<n;i++) { x=getint(); y=getint(); link(x,y); link(y,x); }
dfs(,); Ans=*(n-)-ans+; if(k==) { printf("%d",Ans); return ; }
if(f[root][]>) { x=Son; w[Son2]=-; while(g[x]) { w[p[x]]=-; x=g[x]; } }
x=root; while(g[x]) w[p[x]]=-,x=g[x]; ans=; memset(f,,sizeof(f));
dfs(,); Ans-=ans-; printf("%d",Ans);
} int main()
{
work();
return ;
}

BZOJ1912 [Apio2010]patrol 巡逻的更多相关文章

  1. 【树形dp 最长链】bzoj1912: [Apio2010]patrol 巡逻

    富有思维性的树形dp Description Input 第一行包含两个整数 n, K(1 ≤ K ≤ 2).接下来 n – 1行,每行两个整数 a, b, 表示村庄a与b之间有一条道路(1 ≤ a, ...

  2. BZOJ1912:[APIO2010]patrol巡逻

    Description Input 第一行包含两个整数 n, K(1 ≤ K ≤ 2).接下来 n – 1行,每行两个整数 a, b, 表示村庄a与b之间有一条道路(1 ≤ a, b ≤ n). Ou ...

  3. 2018.11.06 bzoj1912: [Apio2010]patrol 巡逻(树形dp)

    传送门 一道挺妙的题啊. 对于K==1K==1K==1的直接求树的直径. 对于K==2K==2K==2的先求一次直径,然后考虑到如果两条边加进去形成的两个环重叠就会有负的贡献. 因此把之前那条直径上的 ...

  4. 【BZOJ1912】[Apio2010]patrol 巡逻 树形DP

    [BZOJ1912][Apio2010]patrol 巡逻 Description Input 第一行包含两个整数 n, K(1 ≤ K ≤ 2).接下来 n – 1行,每行两个整数 a, b, 表示 ...

  5. 【BZOJ-1912】patrol巡逻 树的直径 + DFS(树形DP)

    1912: [Apio2010]patrol 巡逻 Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 1034  Solved: 562[Submit][St ...

  6. BZOJ 1912:[Apio2010]patrol 巡逻(树直径)

    1912: [Apio2010]patrol 巡逻 Input 第一行包含两个整数 n, K(1 ≤ K ≤ 2).接下来 n – 1行,每行两个整数 a, b, 表示村庄a与b之间有一条道路(1 ≤ ...

  7. [Apio2010]patrol 巡逻

    1912: [Apio2010]patrol 巡逻 Time Limit: 4 Sec  Memory Limit: 64 MBSubmit: 2541  Solved: 1288[Submit][S ...

  8. 【bzoj1912】 Apio2010—patrol 巡逻

    http://www.lydsy.com/JudgeOnline/problem.php?id=1912 (题目链接) 题意 给出一棵树,要求在树上添加K(1 or 2)条边,添加的边必须经过一次,使 ...

  9. P1912: [Apio2010]patrol 巡逻

    这道题讨论了好久,一直想不明白,如果按传统的随便某一个点出发找最长链,再回头,K=2 的时候赋了-1就没法用这种方法找最长链了,于是乎,更强的找最长链的方法就来了..类似于DP的东西吧.先上代码: ; ...

随机推荐

  1. git 解决fatal: Not a git repository

    我用git add file添加文件时出现这样错误: fatal: Not a git repository (or any of the parent directories): .git 提示说没 ...

  2. [转]nodejs npm常用命令

    FROM : http://www.cnblogs.com/linjiqin/p/3765772.html npm是一个node包管理和分发工具,已经成为了非官方的发布node模块(包)的标准.有了n ...

  3. Linux 信号详解二(信号分类,信号处理,kill)

    信号分类 信号分为可靠信号和不可靠信号 不可靠信号的缺点 ①:处理完信号,需要重新再注册信号:②信号可能丢失. Linux已经对缺点①做了优化,现在的不可靠问题主要指的是信号可能丢失 信号还可以分为实 ...

  4. IE6 P标签下DIV无法inline-block

    IE6 P标签下的DIV标签无法inline-block,使其触发了hasLayout属性再用csshack 使其inline还是不行,始终要换行 解决:把div标签替换成非div标签,比如span等 ...

  5. Ros集成开发环境配置

    参考资料: http://blog.csdn.net/yangziluomu/article/details/50848357 ROS使用IDE Eclipse http://blog.csdn.ne ...

  6. vbs mytest

    public Function SaveText(filePath,content)set fso=createobject("scripting.filesystemobject" ...

  7. 2015-2016-2 《Java程序设计》教学进程

    2015-2016-2 <Java程序设计>教学进程 目录 考核方式 寒假准备 教学进程 第00周学习任务和要求 第01周学习任务和要求 第02周学习任务和要求 第03周学习任务和要求 第 ...

  8. css3实践之摩天轮式图片轮播+3D正方体+3D标签云(perspective、transform-style、perspective-origin)

    本文主要通过摩天轮式图片轮播的例子来讲解与css3 3D有关的一些属性. demo预览: 摩天轮式图片轮播(貌似没兼容360 最好用chrome) 3D正方体(chrome only) 3D标签云(c ...

  9. 项目分布式部署那些事(2):基于OCS(Memcached)的Session共享方案

    在不久之前发布了一篇"项目分布式部署那些事(1):ONS消息队列.基于Redis的Session共享,开源共享",因为一些问题我们使用了阿里云的OCS,下面就来简单的介绍和分享下相 ...

  10. Replace Pioneer注册

    以下是目前合法长期使用Replace Pioneer的唯一方法(除了购买之外): Replace Pioneer过期后,会弹出一个注册(Registration)窗口,其中有一个试用选项(Trial ...