补题
j题
跑酷大湿
链接:https://ac.nowcoder.com/acm/contest/121844/J
来源:牛客网
题目描述
Steve 正在挑战一个跑酷地图。地图由 nnn 个平台(编号为 1∼n1 \sim n1∼n )组成,平台之间的连接形成一棵树。初始时,有 mmm 个平台被诅咒,在第 0 秒时这些平台开始着火。之后,火每秒会蔓延到所有与已着火平台相邻的平台(火会一直存在)。
Steve 从平台 sss 出发,每秒他可以移动到一个相邻平台或停留在原地,Steve需要时刻保证他没有站到着火的平台上。他的目标是到达任意一个安全屋(即叶子节点)。
请计算 Steve 需要的最少移动次数(以秒为单位)。如果他从起点 sss 出发时已经在一个安全的叶子节点上,则移动次数为 0。如果无法到达任何安全的叶子节点(或者出发时就已经在一个着火平台上),输出 -1 。
【树】树是指这样的一张图,其由 nnn 个节点和 n−1n-1n−1 条边构成,其上的任意两个点都连通,且不存在环。
【叶子节点】如果一个节点有且仅有一个节点与之相连,那么这个点就是一个叶子节点。
输入描述:
第一行输入三个整数 n(2≤n≤105)n\left(2 \leq n \leq 10^5\right)n(2≤n≤105),m(0≤m≤n)m\left(0 \leq m \leq n\right)m(0≤m≤n),s(1≤s≤n)s\left(1 \leq s \leq n\right)s(1≤s≤n)
第二行输入 mmm 个整数 a1,a2,⋯ ,am(1≤ai≤n)a_1,a_2,\cdots,a_m\left(1\leq a_i \leq n\right)a1,a2,⋯,am(1≤ai≤n)代表着火的点(保证没有重复的点)。
此后 n−1n-1n−1 行,第 iii 行输入两个整数 uiu_iui 和 vi (1≤ui,vi≤n; ui≠vi)v_i\ (1\leq u_i, v_i \leq n;\ u_i \neq v_i)vi (1≤ui,vi≤n; ui=vi) 表示树上第 iii 条边连接节点 uiu_iui 和 viv_ivi 。保证树连通。
输出描述:
输出一个整数表示Steve到达任意一个安全屋需要的最少移动次数,如果无法到达任何安全的叶子节点,输出 -1 。
示例1
输入
复制2 0 1 1 2
2 0 1 1 2
输出
复制0
0
示例2
输入
复制4 1 3 4 1 2 2 3 3 4
4 1 3 4 1 2 2 3 3 4
输出
复制2
2
示例3
输入
复制5 3 2 3 4 5 1 2 1 3 2 4 2 5
5 3 2 3 4 5 1 2 1 3 2 4 2 5
输出
复制-1
-1
bfs问题 bfs一遍火势蔓延 bfs一遍走路 即可;
短板(赛场上暴露的问题): 不会bfs遍历树;
此处用到的遍历树方法: 二维vector 第一维存储自己的序号 第二维存储自己链接的节点 遍历子节点的时候 采取了范围循环 for(auto v:g[u])
#include <bits/stdc++.h>
using namespace std;
int main() {
int n,m,s;
cin>>n>>m>>s;
vector<int>a(m+1);
for(int i=1;i<=m;i++){ //维护着火点
cin>>a[i];
}
vector<vector<int>>g(n+1); //维护每个节点以及其连接的所有节点
for(int i=1;i<=n-1;i++){
int u,v;
cin>>u>>v;
g[u].push_back(v);
g[v].push_back(u);
}
queue<int>q; //bfs 先让每个着火点入队

最低0.47元/天 解锁文章
2674

被折叠的 条评论
为什么被折叠?



