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。

Source

一道画画图就能搞出来的题。。。

首先我们应该想想他让我们修路有什么用。你随便画一棵树就很容易发现,要想从一个点出发经过所有点一遍再回来,每条边是要经过两次的。而我们修路就是为了让其中一些边只走一次。

K=1:显然我们随意连一条边会形成一个环,环上的边我们只用经过一次。这样我们最大化环的的长度就行,也就是找到树的直径。

K=2:首先我们肯定还是连直径。但是第二条边怎么连?显然我们还可以找次长链出来。但如果两条链有重叠怎么办?

我们可以把第一条链在算完长度后将所有边权赋成-1,这样就不会算重了。设两次选的边长度分别为l1,l2,那么答案就是2*n-l1-l2.。

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
struct point
{
int to;
int next;
int dis;
}e[];
int n,k,x,y,l1,l2,num,maxn,s,t;
int pre[],head[],d[],pr[];
bool vis[];
void add(int from,int to,int dis)
{
e[++num].next=head[from];
e[num].to=to;
e[num].dis=dis;
head[from]=num;
}
void dfs1(int x)
{
vis[x]=true;
for(int i=head[x];i!=;i=e[i].next)
{
int to=e[i].to;
if(!vis[to])
{
d[to]=d[x]+e[i].dis;
dfs1(to);
}
}
}
void dfs2(int x)
{
vis[x]=true;
for(int i=head[x];i!=;i=e[i].next)
{
int to=e[i].to;
if(!vis[to])
{
d[to]=d[x]+e[i].dis;
pre[to]=x;
dfs2(to);
}
}
}
void dp(int x)
{
vis[x]=true;
for(int i=head[x];i;i=e[i].next)
{
int to=e[i].to;
if(!vis[to])
{
dp(to);
l2=max(l2,d[to]+d[x]+e[i].dis);
d[x]=max(d[x],d[to]+e[i].dis);
}
}
}
void change()
{
for(int i=t;i!=;i=pre[i])
pr[i]=pre[i];
for(int i=;i<=n;i++)
{
for(int j=head[i];j!=;j=e[j].next)
{
int to=e[j].to;
if(pr[i]==to||pr[to]==i)
e[j].dis=-;
}
}
}
int main()
{
scanf("%d%d",&n,&k);
for(int i=;i<=n-;i++)
{
scanf("%d%d",&x,&y);
add(x,y,);
add(y,x,);
}
dfs1();
for(int i=;i<=n;i++)
if(d[i]>maxn)
{
maxn=d[i];
s=i;
}
memset(vis,false,sizeof(vis));
memset(d,,sizeof(d));
dfs2(s);
for(int i=;i<=n;i++)
if(d[i]>l1)
{
l1=d[i];
t=i;
}
if(k==)
{
printf("%d",*(n-)+-l1);
return ;
}
change();
memset(d,,sizeof(d));
memset(vis,false,sizeof(vis));
dp();
printf("%d",*n-l1-l2);
return ;
}

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

  1. 尝试一下LLJ大佬的理论AC大法

    1.BZOJ 3522 Poi2014 Hotel DFS 给定一棵树,求有多少无序三元组(x,y,z)满足x,y,z互不相等且Dis(x,y)=Dis(y,z)=Dis(x,z) 枚举中心点,分别d ...

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

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

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

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

  4. 【bzoj1912】 Apio2010—patrol 巡逻

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

  5. BZOJ1912 [Apio2010]patrol 巡逻

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转 ...

  6. bzoj1912【Apio2010】patrol 巡逻

    题解: 显然需要分类讨论了,首先理解k==0即原图时按照dfs序来说 , 每条边至少走两次: k==1,相当于可以省去dfs回溯时第二次走过某条路径的浪费,所以答案是k==0的答案-直径 : k==2 ...

  7. BZOJ1912 APIO2010 洛谷P3629 巡逻

    Description: 在一个地区中有 n 个村庄,编号为 1, 2, ..., n.有 n – 1 条道路连接着这些村 庄,每条道路刚好连接两个村庄,从任何一个村庄,都可以通过这些道路到达其 他任 ...

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

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

  9. BZOJ1912:[APIO2010]patrol巡逻

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

随机推荐

  1. Whether to hide the cookie from JavaScript

    w禁用js访问特定cookie. https://codeigniter.com/userguide3/helpers/cookie_helper.html $this->load->he ...

  2. 【题解】P5151 HKE与他的小朋友

    [题解]P5151 HKE与他的小朋友 实际上,位置的关系可以看做一组递推式,\(f(a_i)=f(a_j),f(a_j)=f(a_t),etc...\)那么我们可以压进一个矩阵里面. 考虑到这个矩阵 ...

  3. Flask路由系统与模板系统

    路由系统 @app.route('/user/<username>') @app.route('/post/<int:post_id>') @app.route('/post/ ...

  4. MySQLdb使用批量插入executemany方法插入mysql

    python的MySQLdb库可以使用批量操作executemany,进行多行插入. 比如向user表(username,salt,pwd)插入数据,具体的sql语句如下: sql = 'INSERT ...

  5. POJ1836:Alignment(LIS的应用)

    题目链接:http://poj.org/problem?id=1836 题目要求: 给你n个数,判断最少去掉多少个数,从中间往左是递减的序列,往右是递增的序列 需注意的是中间可能为两个相同的值,如 1 ...

  6. UVA10020:Minimal coverage(最小区间覆盖)

    题目: http://acm.hust.edu.cn/vjudge/contest/view.action?cid=68990#problem/M 题目需求:数轴上有n个闭区间[ai,bi],选择尽量 ...

  7. 存储库之——MongoDB

    阅读目录 一 简介 二 MongoDB基础知识 三 安装 四 基本数据类型 五 CRUD操作 六 可视化工具 七 pymongo 一 简介 MongoDB是一款强大.灵活.且易于扩展的通用型数据库1. ...

  8. PHP计算上一个月最后一天、当月最后一天、下一个月最后一天

    上个月最后一天: $last_month_last_day = date('Y-m-t',strtotime('-1 month')); 当月最后一天: $first_day=date('Y-m-01 ...

  9. 【转】阿里巴巴技术专家杨晓明:基于Hadoop技术进行地理空间分析

    转自:http://www.csdn.net/article/2015-01-23/2823687-geographic-space-base-Hadoop [编者按]交通领域正产生着海量的车辆位置点 ...

  10. Centos上安装python3.5以上版本

    一.准备工作: yum install zlib-devel yum install openssl-devel 二.安装python3.5 wget https://www.python.org/f ...