zoukankan      html  css  js  c++  java
  • [CF1009F] Dominant Indices

    [CF1009F] Dominant Indices - 树上启发式合并,map

    Description

    给定一棵以 (1) 为根的树。设 (d(u,x))(u) 子树中到 (u) 距离为 (x) 的节点数。对于每个点求一个最小的 (k) 使得 (d(u,k)) 最大。

    Solution

    树上启发式合并

    首先脑补出的是比较传统的找重儿子然后用数据结构的写法

    但这里可以实现得更加精巧,我们对每个点维护一个 map 表示他子树中各种深度的点的数量

    (先停一下,脑补一下这样该怎么暴力合并怎么求答案)

    好了,在此基础上加入启发式的操作,我们比较当前点和它所有孩子的 map 大小,把最大的那个 map 换过来(当然顺便要更新一下答案)

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    const int N = 1000005;
    
    int dep[N], ans[N], n;
    vector<int> g[N];
    map<int, int> mp[N];
    
    void dfs(int p, int from)
    {
        dep[p] = dep[from] + 1;
        mp[p][dep[p]]++;
        ans[p] = dep[p];
        for (int q : g[p])
            if (q != from)
            {
                dfs(q, p);
                if (mp[p].size() < mp[q].size())
                {
                    swap(mp[p], mp[q]);
                    ans[p] = ans[q];
                }
                for (auto [dep_q, cnt_dep_q] : mp[q])
                {
                    mp[p][dep_q] += cnt_dep_q;
                    if (mp[p][dep_q] + (dep_q < ans[p]) > mp[p][ans[p]])
                    {
                        ans[p] = dep_q;
                    }
                }
            }
    }
    
    signed main()
    {
        ios::sync_with_stdio(false);
        cin >> n;
        for (int i = 1; i < n; i++)
        {
            int t1, t2;
            cin >> t1 >> t2;
            g[t1].push_back(t2);
            g[t2].push_back(t1);
        }
        dfs(1, 1);
        for (int i = 1; i <= n; i++)
            cout << ans[i] - dep[i] << endl;
    }
    
  • 相关阅读:
    HTTP Status 500
    并发编程的常见约束
    面试之数据库面试题
    HashMap实现原理
    数据结构二叉树知识点总结
    十大经典排序算法详细总结(含JAVA代码实现)
    tensorflow里面共享变量、name_scope, variable_scope等如何理解
    Mxnet学习资源
    测试1
    tensorflow prelu的实现细节
  • 原文地址:https://www.cnblogs.com/mollnn/p/14388027.html
Copyright © 2011-2022 走看看