树形DP

Rinne Loves Edges

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

题面大意

  • 以S为根,全部的叶子结点无法到达s,求最小消耗。
  • 为什么可以得到上方结论,m=n-1,且图不连通,说明这就是一棵树。 那我们如何求得最小消耗呢?
    从S为根节点依次dfs遍历整棵树,我们用dp[s]表示s结点到全部叶子结点的边权值。那么我们可以得到状态转移方程:

    dp[x]+=min(dp[u],w),u是子节点,w为x到u的边权。

    还要注意一点,达到叶子结点应该把叶子结点的dp值改成无穷大

运行程序如下
https://ac.nowcoder.com/acm/contest/view-submission?submissionId=43371967&returnHomeType=1&uid=919749006

Code

#include <bits/stdc++.h>
using namespace std;
#define js ios::sync_with_stdio(false);cin.tie(0); cout.tie(0)
typedef long long ll;

inline int read() {
    int s = 0, w = 1; char ch = getchar();
    while (ch < 48 || ch > 57) { if (ch == '-') w = -1; ch = getchar(); }
    while (ch >= 48 && ch <= 57) s = (s << 1) + (s << 3) + (ch ^ 48), ch = getchar();
    return s * w;
}

const int N = 1e5 + 7;
struct Node {
    int v;
    ll w;
};
vector<Node>    e[N];
ll dp[N];

void dfs(int x, int fa) {
    bool flag = true;
    for (auto it : e[x]) {
        if (it.v != fa) {
            flag = false;
            dfs(it.v, x);
            dp[x] += min(it.w, dp[it.v]);
        }
    }
    if (flag)    dp[x] = 1e18;
}

int main() {
    int n = read(), m = read(), s = read();
    for (int i = 1; i <= m; ++i) {
        int u = read(), v = read(), w = read();
        e[u].push_back({ v,w });
        e[v].push_back({ u,w });
    }
    dfs(s, 0);
    printf("%lld\n", dp[s]);
    return 0;
}
每日一题 文章被收录于专栏

每日一题

全部评论

相关推荐

霁华Tel:秋招结束了,好累。我自编了一篇对话,语言别人看不懂,我觉得有某种力量在控制我的身体,我明明觉得有些东西就在眼前,但身边的人却说啥也没有,有神秘人通过电视,手机等在暗暗的给我发信号,我有时候会突然觉得身体的某一部分不属于我了。面对不同的人或场合,我表现出不一样的自己,以至于都不知道自己到底是什么样子的人。我觉得我已经做的很好,不需要其他人的建议和批评,我有些时候难以控制的兴奋,但是呼吸都让人开心。
点赞 评论 收藏
分享
11-01 08:48
门头沟学院 C++
伤心的候选人在吵架:佬你不要的,能不能拿户口本证明过户给我。。球球了
点赞 评论 收藏
分享
点赞 收藏 评论
分享
牛客网
牛客企业服务