原 CCPC-Wannafly Winter Camp Day7 Div2 A-迷宫(思维)

题目描述

 

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

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

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

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

    在点 11 号点上的人成功逃脱,从这个游戏里消失

现在你需要求的是:让所有人都成功逃脱至少需要多少时间

输入描述

 

第一行一个正整数 nn (1leq nleq 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号点的最小时间。





emmm

发现我的思维真的水 qwq

感觉有点正难则反的意思吧,同时向上的情况不好考虑,那就考虑一下向下走的情况,也就是每个节点从根节点走向自己的位置,

但让上一个走完的deep的时间,这一个点就要走deep加上1的时间,因为两个点不能同事在根节点。



 1 #include<bits/stdc++.h>
 2 using namespace std;
 3  
 4 const int maxn=1e5+5;
 5 int n, a[maxn];
 6 int ans,dis;
 7 vector <int> G[maxn];
 8  
 9 int deep[maxn], fa[maxn];
10 void dfs(int u)
11 {
12     for (auto v : G[u]) if (v != fa[u])
13     {
14         deep[v] = deep[u] + 1;
15         fa[v] = u;
16         dfs(v);
17     }
18 }
19  
20 int main()
21 {
22     scanf("%d",&n);
23     for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
24     for (int i = 1; i < n; i++)
25     {
26         int u,v;
27         scanf("%d%d", &u, &v);
28         G[u].push_back(v);
29         G[v].push_back(u);
30     }
31     deep[1] = 0; dfs(1);
32     vector <int> vec;
33     for (int i = 1; i <= n; i++) if (a[i]) vec.push_back(i);
34     sort(vec.begin(), vec.end(),[](int a,int b)->bool{return deep[a]>deep[b];});
35     for (auto it : vec)
36     {
37         ans = max(ans, dis + deep[it]);
38         ++dis;
39     }
40     printf("%d
", ans);
41     return 0;
42 }
原文地址:https://www.cnblogs.com/zhangbuang/p/10878082.html