CF1453E Dog Snacks

昨天晚上狠狠的被这道题关住了,昨天晚上思考的没有特别仔细,在取最近和最大的问题上想反了。但是大致思路是出来了,其实这题和今年ccpc秦皇岛站的一题很像,都有贪心的策略在里面。

题意:

给定一颗n个节点的树,从一号的出发要最终回到一号点,除了一号点,每个点都只能被访问一次,要做到能走就走,现在求单次步长最大的最小值。

 

题解:

考虑贪心,假若有一颗全是链的子树的树,肯定是从最长链跑到最短链,留在最短的链的叶子节点,这样的贪心是可以模模可以出来的,此时答案就是最长链+1。此时,向上跳的时候,比较的就是每个相邻子树最小链的值,最优还是向上面一样,从最长跳到最短。特别注意到的是,最后一步,跳回到1节点的时候,是用次长+1和最长比较的。其实可以发现,每个子树保留的信息,就是距离子树中的叶子最近的距离。只有当某个节点的儿子个数大于1时,才会考虑更新答案。还要特判一下,根结点儿子只有一个的情况下。

 1 #include <bits/stdc++.h>
 2  
 3 using namespace std;
 4 typedef long long ll;
 5  
 6 const int N = 1e6 + 10;
 7 typedef pair<ll, ll>PLL;
 8 inline int read()
 9 {
10     char ch = getchar();int x = 0, f = 1;
11     while(ch < '0' || ch > '9') {if(ch == '-') f = -1; ch = getchar();}
12     while(ch >= '0' && ch <= '9') {x = (x << 1) + (x << 3) - '0' + ch; ch = getchar();}
13     return x * f;
14 }
15 vector<int>g[N];
16 int n, m, q;
17 int ye[N];
18 int ans;
19 int cmp(int x, int y)
20 {
21     return ye[x] < ye[y];
22 }
23  
24 void dfs(int u, int fa) {
25     if(g[u].size() == 1 && u != 1) ye[u] = 1;
26     vector<int>tmp;
27     for(int i = 0 ;i < g[u].size();i++)
28     {
29         int v = g[u][i];
30         if(v == fa) continue;
31         dfs(v, u);
32         // cout << u << " " << ye[u] << '\n';
33         ye[u] = min(ye[u], ye[v] + 1);
34         tmp.push_back(ye[v]);
35     }
36     sort(tmp.begin(),tmp.end());
37     if(tmp.size() > 1)
38     {
39         int tt = tmp.size();
40       //  cout << u <<" " << tmp[tt - 1]<<" "<< tmp[tt - 2] + 1<< '\n';
41     //    cout << "!" <<" " <<ye[g[u].back()] << " " << ye[tmp[tt - 2]] << '\n';
42         if(u == 1) ans = max(ans, max(tmp[tt - 1], tmp[tt - 2] + 1));
43         else ans = max(ans, tmp.back() + 1);
44     }
45   //  cout << ans << '\n';
46     if(u == 1) ans = max(ans, tmp[0]);
47 }
48  
49 
50 
51 int main()
52 {
53     int t = read();
54     while(t --)
55     {
56         n = read();
57         ans = 0;
58         for (int i = 1; i <= n + 10; i ++)
59         {
60             g[i].clear(), ye[i] = N;
61         }
62         for (int i = 1; i <= n - 1; i ++)
63         {
64             int a = read(), b = read();
65             g[a].push_back(b);
66             g[b].push_back(a);
67         }
68         dfs(1, 0);
69         printf("%d\n", ans);
70     }
71 }
View Code

 

posted @ 2020-12-05 14:37  逾期不候丶  阅读(333)  评论(0编辑  收藏  举报