P3629 [APIO2010]巡逻(树的直径)

2024-08-23 15:58
文章标签 直径 巡逻 apio2010 p3629

本文主要是介绍P3629 [APIO2010]巡逻(树的直径),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目链接


易错点:

  • l2必须要设置全局变量而不能设置局部变量,这是由于设置局部变量无法兼顾所有情况造成的.
  • bfs并设置直径上边权为-1后,如果k=2则不能继续直接使用bfs获得答案,这是bfs的拓展加点性造成的(类比dijkstra).
  • 如果两个变量可以用一个变量导出就用一个变量. 

BFS方法正确性的证明:

  • 如果源点在直径上:显然正确.
  • 如果源点不在直径上:既然源点不在直径上那么直径一定在源点的某棵子树内。由树和直径的性质可知此时直接取最远点然后再进行一次bfs即可求得直径.

#include<cstdio>
#include<iostream>
#include<queue>
#include<cstring>
using namespace std;
const int MAXN=2e5,INF=0x3f3f3f3f;
struct Edge{int from,to,w,nxt;
}e[MAXN*2];
int head[MAXN],edgeCnt=1;
void addEdge(int u,int v,int w){e[++edgeCnt].from=u;e[edgeCnt].to=v;e[edgeCnt].w=w;e[edgeCnt].nxt=head[u];head[u]=edgeCnt;
}
int n;
int d[MAXN],pre[MAXN];
int bfs(int p){memset(d,0x3f,sizeof(d));queue<int> q;q.push(p);d[p]=pre[p]=0;while(!q.empty()){int nowNode=q.front();q.pop();for(int i=head[nowNode];i;i=e[i].nxt){int nowV=e[i].to;if(d[nowV]==INF){d[nowV]=d[nowNode]+e[i].w;pre[nowV]=i;q.push(nowV);}}}int ans=1;for(int i=1;i<=n;i++){if(d[i]>d[ans])ans=i;//如果两个变量可以用一个变量导出就用一个变量. }return ans;
}
int p;
int get(){p=bfs(1);p=bfs(p);return d[p];
}
void change(){for(;pre[p];p=e[pre[p]].from){e[pre[p]].w=e[pre[p]^1].w=-1;}
}
bool vis[MAXN];
int f[MAXN],l2;
void dfs(int p){vis[p]=1;for(int i=head[p];i;i=e[i].nxt){int nowV=e[i].to;if(!vis[nowV]){dfs(nowV);l2=max(l2,f[p]+f[nowV]+e[i].w);f[p]=max(f[p],f[nowV]+e[i].w);}}
}
int main(){int k;scanf("%d%d",&n,&k);for(int i=1;i<=n-1;i++){int a,b;scanf("%d%d",&a,&b);addEdge(a,b,1);addEdge(b,a,1);}int l1=get();if(k==1){printf("%d\n",2*(n-1)-l1+1);return 0;}else{change();dfs(1);printf("%d\n",2*n-l1-l2);return 0;}
}

 

这篇关于P3629 [APIO2010]巡逻(树的直径)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1099840

相关文章

zoj3820(树的直径的应用)

题意:在一颗树上找两个点,使得所有点到选择与其更近的一个点的距离的最大值最小。 思路:如果是选择一个点的话,那么点就是直径的中点。现在考虑两个点的情况,先求树的直径,再把直径最中间的边去掉,再求剩下的两个子树中直径的中点。 代码如下: #include <stdio.h>#include <string.h>#include <algorithm>#include <map>#

poj 1849 Two(树形dp求直径)

树的直径:一棵树中两个点间的最长距离。 Description The city consists of intersections and streets that connect them.  Heavy snow covered the city so the mayor Milan gave to the winter-service a list of streets that ha

POJ 1985 Cow Marathon(树的直径)

题目链接 题意:给出一棵树,求出这个树的直径 解答:任选一点进行dfs,会找到一个最远点s,在以这个最远点s进行dfs,会找到一个最远点是t,那么s-t就是树的直径。 //#include<bits/stdc++.h>#include<cstdio>#include<algorithm>#include<vector>#include<cstring>using namespace

【UE5.1】NPC人工智能——07 NPC在巡逻过程中休息

目录 前言 效果 步骤 一、准备狮子休息的动画 二、实现狮子休息效果 三、随机行为 四、增加行为权重 前言         在上一篇中(【UE5.1】NPC人工智能——06 NPC攻击)我们已经实现了NPC狮子追到玩家后进行攻击的功能。本篇将在上一篇的基础上继续实现NPC在巡逻过程中偶尔休息的功能。 效果 步骤 一、准备狮子休息的动画 1. 找到狮子休息的动画

SDUT OJ 3045 迷之图论 (树的直径)

题目地址:SDUT OJ 3045 这题比赛的时候想的差不多。。但是总是觉得不对。。写了一次就没再写,然后删了。。当时没想到的是第二次求出来的就是最长链。。当时想到的两次bfs找最大值(这一种方法其实结果也对。。TAT。。),还有找到点后在回溯减去重点等等。。但总觉得好像都不太对。。。赛后才知道这题原来是树的直径。。。。。牡丹江区域现场赛的时候遇到过,不过赛后也没看。。。 找树的直径的方法其实

最近公共祖先(LCA),树上差分,树的直径总结

最近也是一不小心就学到了树论,这方面确实太不行了,也该开始学习一下了,那么话不多说,进入今日份的树论学习,直接开冲 最近公共祖先(LCA)——倍增思想(可以结合我之前写的ST表学习)   我们来看什么是最近公共祖先,对于9和8来讲,其最近公共祖先为6,对于3和7来讲,其最近公共祖先为5,那么我们去求最近公共祖先总共要有两步 第一步就是深搜,我们这一遍的深搜主要是为了去统计每一个点的深度

UVa 10308 Roads in the North 树的直径

题目来源:UVa 10308 Roads in the North 题意:求距离最远的2点之间的距离 思路:裸的树的直径 或者树形DP #include <cstdio>#include <cstring>#include <queue>using namespace std;const int maxn = 100010;struct node{int to, w;node()

大数据算法-空间时间亚线性算法举例(水库抽样,平面图直径)

大数据算法-空间时间亚线性算法举例 水库抽样 问题描述 Input:一组数据 Output:这组数据的K个均匀抽样要求: 扫描一次空间复杂度o(k)扫描到前n个数字时,保存当前数据的均匀抽样实现 收到第i个元素t时,以k/i的概率随机替换抽样数组ans[]中的元素证明 均匀: ki×(1−1i+1)×(1−1i+2)×⋯×(1−1n)=kn \frac{k}{i}\tim

校园安保巡逻机器人

2023年8月5日,陕西西安一高校实验室起火冒烟,导致学校化学实验室发生火灾。2022年8月3日,一名歹徒持械闯入江西吉安安福县城的一家私立幼儿园,对着无辜的幼儿行凶伤人,造成3死6伤。 像这样的事故有不断地发生,也导致安全始终是校园的重中之重。然而,当前校园安保面临着诸多棘手的问题和严峻的挑战。比如设施设备安全、消防安全、治安安全等多个层面。传统的校园安全管理对人力的依赖明显,安保人员只能在监

羊毛纤维直径检测 — C++

羊毛纤维检测 系统是 Ubuntu20.04 。 需要用到 OpenCV 的库,库具体该怎么编译配置,可以参考网上的教程。 自己码的一小段函数,用纯 CV 的方式处理羊毛纤维图像,如图所示: 在 wool 下面,创建 build 文件夹,在 build 文件夹下面打开终端,输入命令: cmake ..make -j4 这时在 build 文件夹下会生成一个名为 wool 的可执行文