• 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
  • 相关阅读:
    Spring Tool Suite 配置和使用
    自动提示在线/离线状态
    Excel数据导入数据库的SQL快速生成
    MySQL查询和删除重复数据
    内存不足时,调用ajax报的错
    订单支付成功后存储过程
    下订单存储过程
    课程表,订单表(统计报名人数),评论表(统计评论的人数),点赞表(点赞人数)
    更改浏览器的滚动条样式
    自定义文本选中样式
  • 原文地址:https://www.cnblogs.com/xwdzuishuai/p/14089618.html
Copyright © 2020-2023  润新知