这是一道关于树的直径的好题,值得一刷。

本题有两个难点,一个是分类讨论k,另一个是代码的实现(其实还好)。

本题k可以为1或2,因此我们分类讨论一下。

  • 当k=1时,我们可以任选两个点连接,假设我们一条边都不连接,那么我们需要走2*m次,其中m为边的数量。假设我们在x,y上连一条边,那么我们用1个距离节省了dis(x,y)个距离,为了使答案最小化,我们要使dis(x,y)最大,显然我们求一遍树的直径即可,那么答案为2*m-zhijing+1.
  • 当k=2时,就是在k=1的基础上再加上一条边,同样我们分成两部分讨论。假设这一个环与上一个环没有重合的边,那么问题很简单,只需要在上一个答案的基础上再减去dis(x,y)再+1即可。若这个环与上一个环有重合的部分,为了保证每一条边都被巡逻,那么我们发现重合的这部分需要走两次,环上剩下的部分走一次即可。这是我们把第一次求的直径上的边权都赋值为-1,然后再做一遍树的直径得到的答案就是第二次的解,所以这种情况的答案就是2*m-(zhijing1-1)-(zhijing2-1)=2*m-zhijing1-zhijing2+2.如果对于两个环没有重合的情况,这个答案依然成立。

我们先进行两次bfs求出树的直径,在bfs的同时记录在直径上与每一个点的相连的边,方便之后赋值-1,之后再进行一次树形dp求出树的直径即可。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <queue>
 5 using namespace std;
 6 inline int read() {
 7     int ret=0;
 8     int op=1;
 9     char c=getchar();
10     while(c<'0'||c>'9') {if(c=='-') op=-1; c=getchar();}
11     while(c<='9'&&c>='0') ret=ret*10+c-'0',c=getchar();
12     return ret*op;
13 }
14 struct node {
15     int next,to,dis;
16 }a[100010<<1];
17 int n,head[100010<<1],num=1,k,dis[100010],pre[100010],ret,x,maxx;
18 queue<int> q;
19 inline void add(int from,int to,int dis=1) {
20     a[++num].next=head[from];
21     a[num].to=to;
22     a[num].dis=dis;
23     head[from]=num;
24 }
25 int bfs(int s) {
26     while(!q.empty()) q.pop();
27     memset(dis,0x3f,sizeof(dis));
28     dis[s]=pre[s]=0;
29     q.push(s);
30     while(!q.empty()) {
31         int now=q.front();
32         q.pop();
33         for(int i=head[now];i;i=a[i].next) {
34             int v=a[i].to;
35             if(dis[v]==0x3f3f3f3f) {
36                 dis[v]=dis[now]+a[i].dis;
37                 pre[v]=i;
38                 q.push(v);
39             }
40         }
41     }
42     int y=1;
43     for(int i=1;i<=n;i++)
44         if(dis[i]>dis[y]) y=i;
45     return y;
46 }
47 int zhijing() {
48     ret=bfs(1);
49     ret=bfs(ret);
50     return dis[ret];
51 }
52 int dp(int u,int fa) {
53     int sum1=0,sum2=0;
54     for(int i=head[u];i;i=a[i].next) {
55         int v=a[i].to;
56         if(v==fa) continue ;
57         sum2=max(sum2,dp(v,u)+a[i].dis);
58         if(sum2>sum1) swap(sum2,sum1);
59     }
60     maxx=max(maxx,sum1+sum2);
61     return sum1;
62 }
63 int main() {
64     n=read(); k=read();
65     for(int i=1;i<n;i++) {
66         int x=read(),y=read();
67         add(x,y);
68         add(y,x);
69     }
70     x=zhijing();
71     if(k==1) {
72         printf("%d\n",2*(n-1)-x+1);
73         return 0;
74     }
75     while(pre[ret]) {
76         a[pre[ret]].dis=a[pre[ret]^1].dis=-1;
77         ret=a[pre[ret]^1].to;
78     }
79     dp(1,0);
80     printf("%d\n",2*n-x-maxx);
81     return 0;
82 }

AC Code

转载于:https://www.cnblogs.com/shl-blog/p/10799785.html

【APIO2010】巡逻相关推荐

  1. 【树的直径】解题报告: luogu P3629 [APIO2010]巡逻(树的直径,位运算成对变换,思维)

    题目链接:P3629 [APIO2010]巡逻 首先看题,从1号结点开始,全部遍历并回到1号结点会恰好经过所有的边两次,这样总长度为 2∗(n−1)2*(n-1)2∗(n−1). 那么如果建立一条路以 ...

  2. 树的直径【p3629】[APIO2010]巡逻

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

  3. APIO2010巡逻(树上带权直径)

    题目链接:https://www.luogu.org/problem/show?pid=3629 题解: 看到这题题解一片空白,身为蒟蒻的我也想为社会做点贡献-- 首先要知道: 1.假如不加边,每条边 ...

  4. OI每周刷题记录——lrllrl

    看这标题就知道我是模仿的hzwer大佬,远程%%% 大佬的OI经历让蒟蒻我深受感触,为了晚一些AFO本蒟蒻也得加油了 从高二上期第一周开始计数,每个星期天更一次,一直更到我AFO 如果这是我此生最后一 ...

  5. [APIO2010]

    A.特别行动队 n<=1000000 看了数据范围和题目感觉就像是斜率优化,然后瞎推了一波式子,没想到A了. sij表示i+1到j的权值和. j比k优秀  $$fj+a*sij^{2}+b*si ...

  6. 机器人瓦力船长机器人_警察“瓦力”来啦!机器人巡逻南京路 这样的它你喜欢吗?...

    电影"瓦力"中的机器人主角瓦力让人印象深刻,这两天,一台形似瓦力的机器人出现在了南京路步行街上,一下子就成为了这条街上"最靓的仔",实际上,它是一台功能强大的警 ...

  7. 波士顿动力的机器狗上班了!巡逻、检测不在话下,挪威公司为其编发工号

    作者 | 神经小刀 来源 | HyperAI超神经(ID: HyperAI) AI 界的网红,波士顿动力机器狗 Spot ,近日获得了新的工作岗位,它将入职挪威的石油天然气开采公司 Aker ,负责巡 ...

  8. 无人机巡逻喊话、疫情排查、送药消毒,抗疫战中机器人化身钢铁战士!

    整理 | 夕颜 责编 | Carol 出品 | CSDN(ID:CSDNnews) 这场抗疫战争似乎格外漫长,但回头细数一下才发现,自疫情爆发以来,也不过半月之久.在接下来的几个半月中,抗疫战仍将继续 ...

  9. scau 1142 巡逻的士兵(分治)

    1142 巡逻的士兵 时间限制:1000MS  内存限制:65536K 提交次数:217 通过次数:58 题型: 编程题   语言: G++;GCC Description 有N个士兵站成一队列, 现 ...

最新文章

  1. R语言包_lubridate
  2. 将object类型参数值传递给ObjectDataSource
  3. 成功解决AttributeError: ‘DataFrame‘ object has no attribute ‘tolist‘
  4. tab css html,纯css的tab 切换
  5. VTK:图片之ImageCheckerboard
  6. muduo网络库源码阅读Step by Step
  7. mysql 逻辑备份导入数据库_mysql逻辑备份(mysql dump的使用)
  8. 简单防止通过执行存储过程攻击服务器
  9. python中对文件的操作_Python对文件操作知识
  10. 三行代码实现冒泡排序算法
  11. 【问答】开放领域问答梳理(2)
  12. 关于LAMP配置Let’s Encrypt SSL证书
  13. oracle数据库英语,Oracle的数据库管理功能的学习英语
  14. node.js安装和卸载问题could not access network location *\Program...
  15. lay和lied_lie-lie-lay三个动词的区别
  16. Springboot实战:项目部署
  17. Python模块字典
  18. /proc/mounts介绍
  19. Visial Studio中“变量已被优化掉 因而不可用”的解决方案
  20. 使用Egret粒子编辑器实现烟雾效果

热门文章

  1. MVVM(Knockout.js)的新尝试:多个Page,一个ViewModel
  2. 退化射线和净化装置获得法
  3. 机器人视觉场景理解挑战赛
  4. 图像分割中的深度学习:U-Net 体系结构
  5. 商汤科技62篇论文入选CVPR 2019!多个竞赛项目夺冠!
  6. Kaggle新手银牌:Airbus Ship Detection 卫星图像分割检测
  7. matlab的点平方,性能 – 有效地计算Matlab中的成对平方欧几里德距离
  8. 新手如何开始学习3D建模?美术基础重不重要?
  9. 3详细参数_大疆精灵3值得入手吗?最详细的实测体验,各种参数应有尽有!
  10. 高效新思路!实例分割算法!腾讯、华科出品!入选ICCV 2021!