zoukankan      html  css  js  c++  java
  • 牛客多校Round 2

    Solved:3

    rank:187

    H.travel

    题意:给一颗带有点权的树 找三条不相交的链 使得点权最大

    题解:使用树形DP dp[x][i][0/1] 表示x节点选择i条链 有没有经过x的链

       对于每一个回溯的状态 下面的结点已经处理好了

       但是处理当前结点时还有一种有两条经过x的链 实际上他们可以合成一条链

       为了避免重复计算 经过当前结点的权值在更新时计算

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    
    int n;
    ll val[400005];
    ll dp[400005][4][2];
    vector<int> g[400005];
    
    void dfs(int x, int fa)
    {
        ll tmp[4][3]; ll f[4][3];
        for(int i = 0; i < 4; i++) tmp[i][0] = tmp[i][1] = tmp[i][2] = 0;
        for(int i = 0; i < g[x].size(); i++)
        {
            int v = g[x][i];
            if(v == fa) continue;
            dfs(v, x);
            memcpy(f, tmp, sizeof(tmp));
    
            for(int a = 0; a < 4; a++)
                for(int b = 0; b < 4; b++)
                {
                    if(a + b > 3) continue;
                    for(int c = 0; c < 3; c++)
                        for(int d = 0; d < 2; d++)
                        {
                            if(c + d > 2) continue;
                            tmp[a + b][c + d] = max(tmp[a + b][c + d], f[a][c] + dp[v][b][d]);
                        }
                }
        }
        for(int i = 0; i < 4; i++)
        {
            dp[x][i][0] = max(dp[x][i][0], tmp[i][0]);
            dp[x][i][1] = max(dp[x][i][1], tmp[i][1] + val[x]);
    
            if(i < 3)
            {
                for(int j = 0; j < 2; j++)
                    for(int k = j + 1; k < 3; k++)
                        dp[x][i + 1][j] = max(dp[x][i + 1][j], tmp[i][k] + val[x]);
            }
        }
    }
    
    int main()
    {
        scanf("%d", &n);
        for(int i = 1; i <= n; i++) scanf("%lld", &val[i]);
        for(int i = 1; i < n; i++)
        {
            int u, v;
            scanf("%d%d", &u, &v);
            g[u].push_back(v);
            g[v].push_back(u);
        }
        dfs(1, -1);
        ll ans = 0;
        for(int i = 0; i < 4; i++) ans = max(ans, dp[1][i][0]);
        printf("%lld
    ", ans);
        return 0;
    }
    /*
    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
    */
    View Code

       

  • 相关阅读:
    JEECG SSO kisso
    高级进程间通信之基于STREAMS的管道
    网络IPC:套接字之非阻塞和异步I/O
    网络IPC:套接字之带外数据
    网络IPC:套接字之套接字选项
    网络IPC:套接字之数据传输
    网络IPC:套接字之建立连接
    网络IPC:套接字之寻址
    网络IPC:套接字之套接字描述符
    网络IPC:套接字
  • 原文地址:https://www.cnblogs.com/lwqq3/p/9349715.html
Copyright © 2011-2022 走看看