• 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] << '
    ';
    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<< '
    ';
    41     //    cout << "!" <<" " <<ye[g[u].back()] << " " << ye[tmp[tt - 2]] << '
    ';
    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 << '
    ';
    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
    ", ans);
    70     }
    71 }
    View Code
  • 相关阅读:
    数据结构与算法
    c++学习笔记
    红黑树(map与unorder_map)B B+树
    数据库笔记
    多路复用IO:select poll epoll
    https加密过程!!! 这才是差不多非常详细的https双方获取共用的秘钥过程!!!!!
    助教周报(第一轮)——范青青
    第二十二周助教总结(2021.6.28-7.4)
    第二十一周助教总结(2021.6.21-6.27)
    第二十周助教总结(2021.6.14-6.20)
  • 原文地址:https://www.cnblogs.com/xwdzuishuai/p/14089618.html
Copyright © 2020-2023  润新知