(这道题考察了求直径的两种方法......)

在原图中,每条边要经过两次,增加1条后,形成了一个环,那么环上的边只需要经过一次了(大量画图分析得),再增加一条又会形成一个环,如果这两个环有重叠,重叠部分还是要经过两次,就浪费了,所以我们先找直径(两次dfs),在直径的两个端点连一条边,就可以得到k=1的答案了,如果k=2,将环上的边权都设为-1,再在新图上用DP求新的直径(因为边权有负,要用DP),最后也就得到k=2时的答案了。

 1 #include<bits/stdc++.h>
2 using namespace std;
3 const int N=1e5+10;
4 int to[N<<1],nxt[N<<1],edge[N<<1],head[N],tot;
5 int n,k,p,q;
6 int d[N],pre[N],L2;
7
8 void add(int x,int y){
9 nxt[++tot]=head[x];
10 head[x]=tot;
11 to[tot]=y;
12 edge[tot]=1;
13 }
14
15 void dfs1(int u,int f){
16 if(d[u]>d[p]) p=u;
17 for(int i=head[u];i;i=nxt[i]){
18 int v=to[i];
19 if(v==f) continue;
20 d[v]=d[u]+edge[i];
22 dfs1(v,u);
23 }
24 }
25
26 void dfs2(int u,int f){
27 if(d[u]>d[q]) q=u;
28 for(int i=head[u];i;i=nxt[i]){
29 int v=to[i];
30 if(v==f) continue;
31 d[v]=d[u]+edge[i];
32 pre[v]=i;//记录路径
33 dfs2(v,u);
34 }
35 }
36
37 void update(int q,int p){
38 while(q!=p){
39 edge[pre[q]]=-1;
40 edge[pre[q]^1]=-1;//正反向边都变为-1
41 q=to[pre[q]^1];
42 }
43 }
44
45 void dp(int x,int f){//树形DP求直径
46 //d[]表示向下可以走的最远距离
47 for(int i=head[x];i;i=nxt[i]){
48 int y=to[i];
49 if(y==f) continue;
50 dp(y,x);
51 L2=max(L2,d[y]+d[x]+edge[i]);
52 d[x]=max(d[x],d[y]+edge[i]);
53 }
54 }
55
56 int main(){
57 cin>>n>>k;
58 tot=1;
59 for(int i=1;i<n;i++){
60 int x,y;
61 scanf("%d%d",&x,&y);
62 add(x,y);add(y,x);
63 }
64 dfs1(1,0);
65 memset(d,0,sizeof(d));
66 dfs2(p,0);
67 int ans=2*(n-1)-d[q]+1;
68 if(k==1){
69 cout<<ans<<endl;
70 return 0;
71 }
72 update(q,p);
73 memset(d,0,sizeof(d));
74 dp(1,0);
75 cout<<ans-L2+1<<endl;
76 }

P3629 [APIO2010] 巡逻 (树的直径)的更多相关文章

  1. 洛谷 P3629 [APIO2010]巡逻 解题报告

    P3629 [APIO2010]巡逻 题目描述 在一个地区中有 n 个村庄,编号为 1, 2, ..., n.有 n – 1 条道路连接着这些村 庄,每条道路刚好连接两个村庄,从任何一个村庄,都可以通 ...

  2. 树的直径初探+Luogu P3629 [APIO2010]巡逻【树的直径】By cellur925

    题目传送门 我们先来介绍一个概念:树的直径. 树的直径:树中最远的两个节点间的距离.(树的最长链)树的直径有两种方法,都是$O(N)$. 第一种:两遍bfs/dfs(这里写的是两遍bfs) 从任意一个 ...

  3. 洛谷P3629 [APIO2010]巡逻(树的直径)

    如果考虑不算上新修的道路,那么答案显然为\(2*(n-1)\). 考虑\(k=1\)的情况,会发现如果我们新修建一个道路,那么就会有一段路程少走一遍.这时选择连接树的直径的两个端点显然是最优的. 难就 ...

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

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

  5. [洛谷P3629] [APIO2010]巡逻

    洛谷题目链接:[APIO2010]巡逻 题目描述 在一个地区中有 n 个村庄,编号为 1, 2, ..., n.有 n – 1 条道路连接着这些村 庄,每条道路刚好连接两个村庄,从任何一个村庄,都可以 ...

  6. P3629 [APIO2010]巡逻

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

  7. 洛谷 P3629 [APIO2010]巡逻

    题目在这里 这是一个紫题,当然很难. 我们往简单的想,不建立新的道路时,从1号节点出发,把整棵树上的每条边遍历至少一次,再回到1号节点,会恰好经过每条边两次,路线总长度为$2(n-1)$,根据树的深度 ...

  8. 题解 BZOJ 1912 && luogu P3629 [APIO2010]巡逻 (树的直径)

    本来抄了篇题解,后来觉得题解都太不友好(我太菜了),一气之下自己打...一打打到第二天QAQ 首先什么边也不加时,总路程就是2*(n-1) 考虑k=1的时候,答案显然是2*(n-1)-直径+1=2*n ...

  9. bzoj 1912 : [Apio2010]patrol 巡逻 树的直径

    题目链接 如果k==1, 显然就是直径. k==2的时候, 把直径的边权变为-1, 然后在求一次直径. 变为-1是因为如果在走一次这条边, 答案会增加1. 学到了新的求直径的方法... #includ ...

随机推荐

  1. 当我们谈论算法我们在谈论什么:由疫情核酸检测想到的分治算法(Divide-and-Conquer)

    原文转载自「刘悦的技术博客」https://v3u.cn/a_id_159 北京的疫情一波未平一波又起,由此看来,战"疫"将是一场旷日持久的战争,绝不能掉以轻心.轻易言胜.病毒随时 ...

  2. mosquitto使用的基本流程以及一些遇见的问题

    改配置文件 以记事本的方式打开mosquitto.conf更改部分内容,找到# listener port-number [ip address/host name/unix socket path] ...

  3. 技术分享 | MySQL中MGR中SECONDARY节点磁盘满,导致mysqld进程被OOM Killed

    欢迎来到 GreatSQL社区分享的MySQL技术文章,如有疑问或想学习的内容,可以在下方评论区留言,看到后会进行解答 在MGR测试中,人为制造磁盘满问题后,节点被oom killed 问题描述 在对 ...

  4. 美女 Committer 手把手教你部署 Apache DolphinScheduler 单机版

    还在为如何部署Apache DolphinScheduler 发愁么?自上篇<美女 Committer 手把手教你使用海豚调度>的视频发布后,受到社区伙伴们的热烈欢迎.但个别小伙伴在部署这 ...

  5. 美女 Committer 手把手教你使用海豚调度

    还在为选哪个调度发愁么?还在为查使用手册愁眉不展么?来来来,先瞧一眼海豚调度的 Slogan:调度选的好,下班回家早.调度用的对,半夜安心睡.为充分贯彻这一宗旨,海豚调度一条龙服务来了,特地邀请海豚社 ...

  6. 在 Linux 中安装 MongoDB 的流程

    下载 MongoDB官网下载社区版的安装包: 解压 上传至 Linux,安装位置自行选择.把压缩包解压到安装的目录下. 可重命名解压的文件夹名: mv mongodb-linux-x86_64-rhe ...

  7. Shell 脚本报错 line x: [xxx: command not found

    [root@VM-0-6-centos sh_scripts]# bash val.sh username: hello world! val.sh: line 5: [hello: command ...

  8. 一文搞懂 Python 的模块和包,在实战中的最佳实践

    最近公司有个项目,我需要写个小爬虫,将爬取到的数据进行统计分析.首先确定用 Python 写,其次不想用 Scrapy,因为要爬取的数据量和频率都不高,没必要上爬虫框架.于是,就自己搭了一个项目,通过 ...

  9. C++中的cout.setf(ios::fixed)是什么意思?

    问题描述:在阅读一段代码时,发现代码的最后一部分出现 ... cout.setf(ios::fixed); cout.setf(ios::showpoint); ... 解决: cout.setf() ...

  10. Linux之Samba服务器搭建

    一,samba的基本概念 SMB(Server Messages Block,信息服务块)是一种在局域网上共享文件和打印机的一种通信协议,它为局域网内的不同计算机之间提供文件及打印机等资源的共享服务. ...