题目描述
有一个 nn 个点 n-1n−1 条边的无向连通图迷宫,其中有些点上面有人
现在所有人的目标都是逃离这个迷宫,而迷宫的出口是 11 号点,每一时刻,会依次发生以下的事情:
-
在点 xx 上的人选择一个点 f(x)f(x) 作为目标,要求 f(x)f(x) 必须是 xx,或者与 xx 有边相连的点,且对于 x\neq yx̸=y,有 f(x)\neq f(y)f(x)̸=f(y)
-
在点 xx 上的人移动到 f(x)f(x)
-
在点 11 号点上的人成功逃脱,从这个游戏里消失
现在你需要求的是:让所有人都成功逃脱至少需要多少时间
输入描述
第一行一个正整数 nn (1\leq n\leq 10^5)(1≤n≤105)
第二行 nn 个整数 a_1...a_na1...an,a_i=1ai=1 表示一开始第 ii 个点上有人,a_i=0ai=0 则表示没有,保证 a_1=0a1=0
接下来 n-1n−1 行,每行两个正整数 (u,v)(u,v) 描述图中的一条无向边
输出描述
输出让所有人成功逃脱至少需要多少时间
样例输入 1
4 0 0 1 1 1 2 2 3 2 4
样例输出 1
3
相当于是所有人从1号点出发,回到自己的位置 (要注意同一时刻不能有两个点移动到同一个位置)
深度大的优先,每个人的时间就是等待时间加上深度
取max就行了
#include<bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int n, a[maxn];
int ans,dis;
vector <int> G[maxn];
int deep[maxn], fa[maxn];
void dfs(int u)
{
for (auto v : G[u]) if (v != fa[u])
{
deep[v] = deep[u] + 1;
fa[v] = u;
dfs(v);
}
}
int main()
{
scanf("%d",&n);
for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
for (int i = 1; i < n; i++)
{
int u,v;
scanf("%d%d", &u, &v);
G[u].push_back(v);
G[v].push_back(u);
}
deep[1] = 0; dfs(1);
vector <int> vec;
for (int i = 1; i <= n; i++) if (a[i]) vec.push_back(i);
sort(vec.begin(), vec.end(),[](int a,int b)->bool{return deep[a]>deep[b];});
for (auto it : vec)
{
ans = max(ans, dis + deep[it]);
++dis;
}
printf("%d\n", ans);
return 0;
}