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;
}

原文地址:https://www.cnblogs.com/MingSD/p/10113179.html

时间: 2024-08-06 14:21:08

CodeForces 1084D The Fair Nut and the Best Path的相关文章

Codeforces Round #526 (Div. 2) D. The Fair Nut and the Best Path

D. The Fair Nut and the Best Path 题目链接:https://codeforces.com/contest/1084/problem/D 题意: 给出一棵树,走不重复的路径,每到一个结点加上其权值,经过一条边减去其权值,路径中途减去后不能出现负数,问怎么选择路径可以让最后得到的最大. 题解: 这题考虑用dp来做. 我们定义dp[u]为走到u点的最大值,注意这里的方向,是走到u点.题目中的意思是路径不能走回头路. 对于一个父节点u,那么我们可以根据走到其儿子结点的最

CodeForces 1084A The Fair Nut and Elevator 题解

A. The Fair Nut and Elevator time limit per test : 1 second memory limit per test : 256 megabytes input : standard input output : standard output The Fair Nut lives in ?? story house. ???? people live on the ??-th floor of the house. Every person use

D. The Fair Nut and the Best Path

https://codeforces.com/contest/1084/problem/D?tdsourcetag=s_pctim_aiomsg 题意:一个树,点有值,边有值,求任意两点之间的最大值,遇到点要加它对应的值,遇到边减掉它对应的值. 思路:嗯,题意理解做法水的一笔,任意两点的路径的最大值,可以采用dfs,回溯到父亲结点,与它两个较大的(可能一个或零个)子节点的路径构成最大路径. #include<bits/stdc++.h> using namespace std; #define

D. The Fair Nut and the Best Path 树形dp (终于会了)

#include<bits/stdc++.h> #define int long long using namespace std; const int maxn=3e5+10; int a[maxn]; int dp[maxn]; int visit[maxn]; vector<int> vs[maxn]; map<pair<int,int>,int> mp; int ans=0; void dfs(int x) { visit[x]=1; int max

Codeforces Round #526 (Div. 2) C. The Fair Nut and String

C. The Fair Nut and String 题目链接:https://codeforces.com/contest/1084/problem/C 题意: 给出一个字符串,找出都为a的子序列(比如ai,aj,ak)满足以下条件的个数: 1.子序列的索引单增(i<j<k): 2.在原字符串中,若ai=aj=ak=a,那么满足i<=k1<j,j<=k2<k 并且 ak1=ak2=b. 通俗点说,就是找这样的子序列个数:要么单个a,要么每个a之间都有一个b. 题解:

Codeforces Round #526 (Div. 2) E. The Fair Nut and Strings

E. The Fair Nut and Strings 题目链接:https://codeforces.com/contest/1084/problem/E 题意: 输入n,k,k代表一共有长度为n的多少个字符串.然后给出一个最小字符串s,最大字符串t,满足对于所有的k个字符串有s<=S<=t. 最后求满足条件的k个字符串(自己构造)的不同前缀数量的和. 题解: 这题很巧妙,设dp(i)表示长度为i的前缀的数量和,一开始有dp(1)=0. 后来随着长度的增加,我们每次可以在最后加一个a或者b,

codeforces 897A Scarborough Fair 暴力签到

codeforces 897A Scarborough Fair 题目链接: http://codeforces.com/problemset/problem/897/A 思路: 暴力大法好 代码: #include <iostream> #include <stdio.h> #include <string.h> using namespace std; typedef long long ll; int n,m; string s; int main() { ios

Codeforces Round #526 C - The Fair Nut and String /// 组合递推

题目大意: 给定原字符序列 找出其中所有子序列满足 1.序列内字符都为a 2.若有两个以上的字符 则相邻两个字符在原序列中两者之间存在字符b 的数量 将整个字符序列用b分开 此时再得到每个b之间a的数量 即 abbgaaba 得到 v[] = { 1 0 2 1 } 此时假设到第 i-1 段 已得到在第 i-1 段内的所有方案数为 ans (长度为1.2.3.... .i-1) 则在第 i 段时 可由前一段的方案数 和 当前段数量 组合得到ans*v[ i ] (长度为2.3.4.... .i)

CodeForces - 1073D Berland Fair

XXI Berland Annual Fair is coming really soon! Traditionally fair consists of nnbooths, arranged in a circle. The booths are numbered 11 through nn clockwise with nnbeing adjacent to 11. The ii-th booths sells some candies for the price of aiai burle