• 送快递(贪心+树形结构)


    题意

    给一棵(n)个点的树,每条边的边权为(1)。从(0)号点开始走,问走(k)步,最多能都多少个不重复的点(包括(0)号点)

    数据范围

    (2 leq n leq 1000)
    (1 leq k leq 3000)

    思路

    贪心。可以先考虑最长链,只有最长链走的尽可能长,才会使得结果最优。最长链上的点,每走一步,都会走到一个新点
    然后再考虑非最长链上的点,如果要走非最长链上的点,那么就需要从最长链上的点走过去,然后再回到最长链上,相当于路径走了两次,也就是每走两步,会到达一个新点。
    那么我们可以先统计最长链上点的个数,与(k)比较,然后再看看剩下的步数能走多少点。

    代码

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    
    using namespace std;
    
    const int N = 1010, M = 2 * N;
    
    int n, k;
    int h[N], e[M], ne[M], idx;
    int dist[N];
    
    void add(int a, int b)
    {
        e[idx] = b, ne[idx] = h[a], h[a] = idx ++;
    }
    
    void dfs(int u, int fa, int dep)
    {
        dist[u] = dep;
        for(int i = h[u]; ~i; i = ne[i]) {
            int j = e[i];
            if(j == fa) continue;
            dfs(j, u, dep + 1);
        }
    }
    
    int main()
    {
        memset(h, -1, sizeof(h));
        scanf("%d%d", &n, &k);
        int cnt = n;
        for(int i = 1; i <= n; i ++) {
            int x;
            scanf("%d", &x);
            add(i, x), add(x, i);
        }
        dfs(0, -1, 0);
        int max_long = 0;
        for(int i = 1; i <= n; i ++) max_long = max(max_long, dist[i]);
        if(k <= max_long) printf("%d
    ", k + 1);
        else {
            cnt -= max_long + 1;
            k -= max_long;
            int ans = max_long + 1;
            k /= 2;
            if(k >= cnt) ans += cnt;
            else ans += k;
            printf("%d
    ", ans);
        }
        return 0;
    }
    
  • 相关阅读:
    Gitlab邮箱配置
    Zabbix邮件告警提示Couldn't resolve host name解决办法
    Gitlab备份和恢复操作
    Gitlab权限管理
    编译安装Nginx
    [0] 数据库读写分离
    [0] C# & MongoDB
    [0] 平衡二叉树
    [0] 分布式存储 Memcached
    [0] MSSQL 分库查询
  • 原文地址:https://www.cnblogs.com/miraclepbc/p/14328624.html
Copyright © 2020-2023  润新知