题解 | #吉吉王国#

吉吉王国

https://ac.nowcoder.com/acm/problem/210473

题目想法

这是Rinne Loves Edges的扩展版, 依然是剪掉一些路径从而达到题目要求, 但多了一重限制, 不过不影响核心思路

题目要求

要剪去所有叶子结点路径(可以剪去叶子结点, 也可以剪去叶子结点的某个根结点), 并且总权值要小于等于m. 而题目要求的结果为 求剪去所有叶子结点且总权值小于等于m的所有方案中, 最长边最短的值

题目思路

二分求最优解, 典型二分思路, 每次二分最长边的值, 即最长边为x时, 剪去叶子结点总权值是否小于等于m, 若满足条件则更新res答案值
注意如果最大值INF设为0x3f3f3f3f, 要用到long long, 不然会爆, 所以我的代码中设为的1e7 + 10, 因为懒得改long long了

代码实现

#include <bits/stdc++.h>

#define INF 1e7 + 10

using namespace std;

const int N = 1010, M = N * 2;

int n, m;
int e[M], w[M], ne[M], h[N], idx;
int f[N];

void add(int a, int b, int c)
{
    e[idx] = b, ne[idx] = h[a], w[idx] = c, h[a] = idx ++ ;
}

void dfs(int u, int father, int x)
{
    bool is_leaf = true;
    for (int i = h[u]; i != -1; i = ne[i])
    {
        int j = e[i];
        if (j == father) continue;
        dfs(j, u, x);
        is_leaf = false;
        f[u] += min(f[j], w[i] > x ? f[j] : w[i]);
    }
    if (is_leaf) f[u] = INF;
}

int main()
{
    scanf("%d%d", &n, &m);

    memset(h, -1, sizeof h);

    for (int i = 0; i < n - 1; i ++ )
    {
        int a, b, c;
        scanf("%d%d%d", &a, &b, &c);
        add(a, b, c), add(b, a, c); 
    }

    int l = 0, r = 1e6 + 10;
    int res = 0;
    while (l < r)
    {
        int mid = l + r >> 1;
        memset(f, 0, sizeof f);
        dfs(1, -1, mid);
        if (f[1] <= m) r = mid, res = r;
        else l = mid + 1;
    }

    if (!res) puts("-1");
    else printf("%d\n", res);

    return 0;
}
全部评论

相关推荐

和蔼:在竞争中脱颖而出,厉害! 但是有一个小问题:谁问你了?😡我的意思是,谁在意?我告诉你,根本没人问你,在我们之中0人问了你,我把所有问你的人都请来 party 了,到场人数是0个人,誰问你了?WHO ASKED?谁问汝矣?誰があなたに聞きましたか?누가 물어봤어?我爬上了珠穆朗玛峰也没找到谁问你了,我刚刚潜入了世界上最大的射电望远镜也没开到那个问你的人的盒,在找到谁问你之前我连癌症的解药都发明了出来,我开了最大距离渲染也没找到谁问你了我活在这个被辐射蹂躏了多年的破碎世界的坟墓里目睹全球核战争把人类文明毁灭也没见到谁问你了
点赞 评论 收藏
分享
5 收藏 评论
分享
牛客网
牛客企业服务