Nowcoder-2018ACM多校训练营(第二场)H travel

时间限制:C/C++ 2秒,其他语言4秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld

题目描述 

White Cloud has a tree with n nodes.The root is a node with number 1. Each node has a value.
White Rabbit wants to travel in the tree 3 times. In Each travel it will go through a path in the tree.
White Rabbit can't pass a node more than one time during the 3 travels. It wants to know the maximum sum value of all nodes it passes through.

 

 

输入描述:

The first line of input contains an integer n(3 <= n <= 400001)
In the next line there are n integers in range [0,1000000] denoting the value of each node.
For the next n-1 lines, each line contains two integers denoting the edge of this tree.

输出描述:

Print one integer denoting the answer.

示例1

输入

复制

13
10 10 10 10 10 1 10 10 10 1 10 10 10
1 2
2 3
3 4
4 5
2 6
6 7
7 8
7 9
6 10
10 11
11 12
11 13

输出

复制

110

题意:在树上找3条不相交链,要求链上权值和最大

题解:树型dp,设dp[u][j][k]:以u为顶点的子树上有j条不相交链,k=0表示顶点不可被父节点连接,k=1表示顶点可被父节点连接。一堆转移方程,写的时候漏掉好几个,WA到想吐血系列。。。

#include<bits/stdc++.h>
#define x first
#define y second
using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const int MX = 1e6 + 5;

struct Edge {
    int v, nxt;
} E[MX * 2];
int head[MX], tot;

void init (int n) {
    for (int i = 1; i <= n; i++) head[i] = -1;
    tot = 0;
}

void edge_add (int u, int v) {
    E[tot] = (Edge) {v, head[u]}; head[u] = tot++;
}

int a[MX];
LL dp[MX][4][2], t[MX][4][2];

inline LL Max (LL d[2]) {
    return max (d[0], d[1]);
}

void dfs (int u, int pre) {
    memset (dp[u], 0, sizeof (dp[u]) );
    memset (t[u], 0, sizeof (t[u]) );
    dp[u][1][1] = a[u];
    for (int i = head[u]; ~i; i = E[i].nxt) {
        int v = E[i].v;
        if (v == pre) continue;
        dfs (v, u);
        dp[u][3][0] = max (dp[u][3][0], Max (dp[v][3]) );
        dp[u][3][0] = max (dp[u][3][0], Max (dp[v][2]) + Max (t[u][1]) );
        dp[u][3][0] = max (dp[u][3][0], Max (dp[v][1]) + Max (t[u][2]) );
        dp[u][3][0] = max (dp[u][3][0], a[u] + t[u][1][1] + dp[v][3][1]);
        dp[u][3][0] = max (dp[u][3][0], a[u] + t[u][2][1] + dp[v][2][1]);
        dp[u][3][0] = max (dp[u][3][0], a[u] + t[u][3][1] + dp[v][1][1]);
        dp[u][3][0] = max (dp[u][3][0], dp[u][2][0] + Max (dp[v][1]) );
        dp[u][3][0] = max (dp[u][3][0], dp[u][1][0] + Max (dp[v][2]) );
        dp[u][3][1] = max (dp[u][3][1], a[u] + dp[v][3][1]);
        dp[u][3][1] = max (dp[u][3][1], a[u] + max (dp[v][2][1] + Max (t[u][1]), Max (dp[v][2]) + t[u][1][1]) );
        dp[u][3][1] = max (dp[u][3][1], a[u] + max (dp[v][1][1] + Max (t[u][2]), Max (dp[v][1]) + t[u][2][1]) );
        dp[u][3][1] = max (dp[u][3][1], a[u] + Max (dp[v][2]) );
        dp[u][3][1] = max (dp[u][3][1], a[u] + Max (dp[v][1]) + Max (t[u][1]) );

        dp[u][2][0] = max (dp[u][2][0], Max (dp[v][2]) );
        dp[u][2][0] = max (dp[u][2][0], Max (dp[v][1]) + Max (t[u][1]) );
        dp[u][2][0] = max (dp[u][2][0], a[u] + t[u][1][1] + dp[v][2][1]);
        dp[u][2][0] = max (dp[u][2][0], a[u] + t[u][2][1] + dp[v][1][1]);
        dp[u][2][0] = max (dp[u][2][0], dp[u][1][0] + Max (dp[v][1]) );
        dp[u][2][1] = max (dp[u][2][1], a[u] + dp[v][2][1]);
        dp[u][2][1] = max (dp[u][2][1], a[u] + max (dp[v][1][1] + Max (t[u][1]), Max (dp[v][1]) + t[u][1][1]) );
        dp[u][2][1] = max (dp[u][2][1], a[u] + Max (dp[v][1]) );

        dp[u][1][0] = max (dp[u][1][0], Max (dp[v][1]) );
        dp[u][1][0] = max (dp[u][1][0], a[u] + dp[v][1][1] + t[u][1][1]);
        dp[u][1][1] = max (dp[u][1][1], a[u] + dp[v][1][1]);


        t[u][3][0] = max (t[u][3][0], Max (dp[v][3]) );
        t[u][3][0] = max (t[u][3][0], Max (dp[v][2]) + Max (t[u][1]) );
        t[u][3][0] = max (t[u][3][0], Max (dp[v][1]) + Max (t[u][2]) );
        t[u][3][1] = max (t[u][3][1], dp[v][3][1]);
        t[u][3][1] = max (t[u][3][1], max (dp[v][2][1] + Max (t[u][1]), Max (dp[v][2]) + t[u][1][1]) );
        t[u][3][1] = max (t[u][3][1], max (dp[v][1][1] + Max (t[u][2]), Max (dp[v][1]) + t[u][2][1]) );

        t[u][2][0] = max (t[u][2][0], Max (dp[v][2]) );
        t[u][2][0] = max (t[u][2][0], Max (dp[v][1]) + Max (t[u][1]) );
        t[u][2][1] = max (t[u][2][1], dp[v][2][1]);
        t[u][2][1] = max (t[u][2][1], max (dp[v][1][1] + Max (t[u][1]), Max (dp[v][1]) + t[u][1][1]) );

        t[u][1][0] = max (t[u][1][0], Max (dp[v][1]) );
        t[u][1][1] = max (t[u][1][1], dp[v][1][1]);
    }
}

int main() {
    int n;
    //freopen ("in.txt", "r", stdin);
    while (~scanf ("%d", &n) ) {
        init (n);
        for (int i = 1; i <= n; i++) scanf ("%d", &a[i]);
        for (int i = 1; i < n; i++) {
            int u, v;
            scanf ("%d%d", &u, &v);
            edge_add (u, v);
            edge_add (v, u);
        }
        dfs (1, -1);

        printf ("%lld\n", Max (dp[1][3]) );
    }
    return 0;
}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值