zoukankan      html  css  js  c++  java
  • [CF1453E] Dog Snacks

    [CF1453E] Dog Snacks - 树形dp

    Description

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

    Solution

    基本思路是,处理完一个子树以后,再去处理另一个子树

    对每个结点,我们维护一个跳出距离,即进入这个子树后,最后退出时的最小距离,换句话说,其实就是到最近的叶子的距离

    那么对于任意一个内部分支点,它对答案的贡献,就是其所有子树中最大的跳出距离 + 1

    这里有的跳出距离充当的是在子树间横跳,有的是跳出整个子树,但无论如何,其贡献都可以这样表示

    对于叶子,贡献自然为 0

    对于根,比较特殊,由于最后不需要跳出去,所以不能按上面那样算,需要修正为,各个子树间,最大的跳出距离 和 次大的跳出距离 + 1 之间的较大值

    对于只有一个孩子的内部点,不需要统计贡献

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    
    const int N = 1e6 + 5;
    vector<int> g[N];
    int h[N];
    vector<int> seq;
    int ans = 0;
    
    void dfs1(int p, int from)
    {
        h[p] = 1e18;
        for (auto q : g[p])
        {
            if (q == from)
                continue;
            dfs1(q, p);
            h[p] = min(h[p], 1 + h[q]);
        }
        if (h[p] == 1e18)
            h[p] = 0;
    }
    
    void dfs2(int p, int from)
    {
        int fir = 0, sec = 0;
        for (auto q : g[p])
        {
            if (q == from)
                continue;
            dfs2(q, p);
            if (h[q] + 1 >= fir)
            {
                sec = fir;
                fir = h[q] + 1;
            }
            else
            {
                if (h[q] + 1 > sec)
                    sec = h[q] + 1;
            }
        }
        if (p != 1)
        {
            if (g[p].size() >= 3)
            {
                ans = max(ans, fir + 1);
            }
        }
        else
        {
            ans = max(ans, max(fir, sec + 1));
        }
    }
    
    void solve()
    {
        int n;
        cin >> n;
    
        for (int i = 1; i <= n; i++)
            g[i].clear();
        for (int i = 1; i <= n; i++)
            h[i] = 0;
        seq.clear();
        ans = 0;
    
        for (int i = 1; i < n; i++)
        {
            int u, v;
            cin >> u >> v;
            g[u].push_back(v);
            g[v].push_back(u);
        }
    
        dfs1(1, 0);
    
        dfs2(1, 0);
    
        cout << ans << endl;
    }
    
    signed main()
    {
        ios::sync_with_stdio(false);
    
        int t;
        cin >> t;
    
        while (t--)
        {
            solve();
        }
    }
    
  • 相关阅读:
    深度学习中常见问题
    freespace
    跑superpixel的程序
    python处理图片的一些操作
    跑edgebox
    tensorflow安装
    matlab启动
    stixel 理解
    stixel-world跑在kitti数据集
    小议中国人的乡土情结
  • 原文地址:https://www.cnblogs.com/mollnn/p/14498372.html
Copyright © 2011-2022 走看看