CCPC-Wannafly Winter Camp Day7 (Div2, onsite) A 迷宫

题目描述

有一个 nn 个点 n-1n−1 条边的无向连通图迷宫,其中有些点上面有人

现在所有人的目标都是逃离这个迷宫,而迷宫的出口是 11 号点,每一时刻,会依次发生以下的事情:

  1. 在点 xx 上的人选择一个点 f(x)f(x) 作为目标,要求 f(x)f(x) 必须是 xx,或者与 xx 有边相连的点,且对于 x\neq yx̸​=y,有 f(x)\neq f(y)f(x)̸​=f(y)

  2. 在点 xx 上的人移动到 f(x)f(x)

  3. 在点 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;
}

猜你喜欢

转载自blog.csdn.net/wzazzy/article/details/86662600