• CodeForces 1084D The Fair Nut and the Best Path


    The Fair Nut and the Best Path

    题意:求路径上的 点权和 - 边权和 最大, 然后不能存在某个点为负数。

    题解:

    dfs一遍, 求所有儿子走到这个点的最大值和次大值。

    我们需要明白如果可以从u -> v  那么一定可以从 v -> u, 当然 指的是 u->v是路径上的最大和。

    u->e1->v;

    假如:val[u] = 100, val[e1] = 50, val[v] = 60, 那么我们发现可以从 u -> v 也可以从v -> u

    val[u] = 100, val[e1] = 50, val[v] = 40, 虽然我们可以从u->v,但是 不能 v->u, 但是根据上面的定义,我们发现 从 u->v反而是亏本的,也就是说 u->u是最大的,我们不在考虑 u->v了。

    val[u] = 40, val[e1] = 50, val[v] = 100, 和上面一样的道理。

    所以,当一条路是最大的能赚的话, 那么一定可以走双向。

    然后 现在还有一个疑问就是  如果从 u的父节点到u呢, 这个东西在 u往上传的时候就解决了。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout);
    #define LL long long
    #define ULL unsigned LL
    #define fi first
    #define se second
    #define pb push_back
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    #define lch(x) tr[x].son[0]
    #define rch(x) tr[x].son[1]
    #define max3(a,b,c) max(a,max(b,c))
    #define min3(a,b,c) min(a,min(b,c))
    typedef pair<int,int> pll;
    const int inf = 0x3f3f3f3f;
    const int _inf = 0xc0c0c0c0;
    const LL INF = 0x3f3f3f3f3f3f3f3f;
    const LL _INF = 0xc0c0c0c0c0c0c0c0;
    const LL mod =  (int)1e9+7;
    const int N = 3e5 + 100;
    const int M = 2*N;
    int head[N], to[M], val[M], nt[M], tot;
    void add(int u, int v, int w){
        to[tot] = v;
        val[tot] = w;
        nt[tot] = head[u];
        head[u] = tot++;
    }
    LL dp[N][2];
    int a[N];
    LL ans = 0;
    LL dfs(int o, int u){
        for(int i = head[u]; ~i; i = nt[i]){
            int v = to[i];
            if(v == o) continue;
            LL tmp = dfs(u,v) - val[i];
            if(tmp > dp[u][0]) swap(tmp, dp[u][0]);
            if(tmp > dp[u][1]) swap(tmp, dp[u][1]);
        }
        ans = max(ans, dp[u][0]+dp[u][1]+a[u]);
        return dp[u][0] + a[u];
    }
    int main(){
        int n, u, v, w;
        scanf("%d", &n);
        memset(head, -1, sizeof(head));
        for(int i = 1; i <= n; ++i) scanf("%d", &a[i]);
        for(int i = 1; i < n; ++i){
            scanf("%d%d%d", &u, &v, &w);
            add(u,v,w);
            add(v,u,w);
        }
        dfs(0,1);
        cout << ans << endl;
        return 0;
    }
    View Code
  • 相关阅读:
    单页面应用和多页面应用区别及优缺点
    Vue中双向数据绑定是如何实现的?
    vue组件中data为什么必须是一个函数?
    $nextTick的使用
    分别简述computed和watch的使用场景
    webpack结合postcss-loader实现css样式浏览器兼容前缀的添加
    KeyError:‘uid' Python常见错误
    GO语言学习之 跨平台编译
    图表动态选择+图表联动
    软件需求与分析大作业进度八
  • 原文地址:https://www.cnblogs.com/MingSD/p/10113179.html
Copyright © 2020-2023  润新知