zoukankan      html  css  js  c++  java
  • HDU 2196 Computer

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2196

    思路:

    做法$1:$

    $spfa$,暴力扫。

    复杂度:$O(T imes 2n^2)$。

    显然布星。

    做法$2:$

    树形$dp$。

    对于一个点$v$,到其他的最长距离,可以由它的子树转移,也可以由它的父节点$u$的子树转移。

    但$u$的子树中的最优解可能会有$v$来组成,所以要进行特殊处理。

    即处理由其子树转移过来的状态时,记录其贡献的最大值和次大值,和选择哪个子节点使得贡献最大。

    从父节点转移过来时,进行判断,要么从最大值转移,要么从次大值转移。(因为如果当前节点组成了最优解,则父节点子树的状态就无法转移过来)。

    $f[i][0]$表示以$i$为根的子树中的最大贡献。

    $f[i][1]$表示以$i$为根的子树中的次大贡献。

    $f[i][2]$表示$i$的父节点的最大贡献。

    代码:

    #include <cstdio>
    #include <cctype>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #include <vector>
    const int MAXN = 10050;
    using namespace std;
    struct node {
        int to, val;
    };
    vector<node> g[MAXN];
    int n, v, w, f[MAXN][5], ro[MAXN];
    void init() {
        for(int i = 1; i <= n; i++)
            g[i].clear();
        memset(f, 0, sizeof(f));
    }
    void dfs1(int x, int fa) {
        int Max1 = 0, Max2 = 0;
        for(int i = 0; i < (int)g[x].size(); i++) {
            int to = g[x][i].to, val = g[x][i].val;
            if(to == fa)
                continue;
            dfs1(to, x);
            if(Max1 < f[to][0] + val) {
                Max2 = Max1;
                Max1 = f[to][0] + val;
                ro[x] = to; 
            }
            else
                Max2 = max(Max2, f[to][0] + val);
        }
        f[x][0] = Max1;
        f[x][1] = Max2;
    }
    void dfs2(int x, int fa) {
        for(int i = 0; i < (int)g[x].size(); i++) {
            int to = g[x][i].to, val = g[x][i].val;
            if(to == fa)
                continue;
            f[to][2] = max(((ro[x] == to) ? f[x][1] : f[x][0]) + val, f[x][2] + val);
            dfs2(to, x);
        }
    }
    int main() {
        while(scanf("%d", &n) == 1) {
            for(int i = 2; i <= n; i++) {
                cin >> v >> w;
                g[i].push_back((node){v, w});
                g[v].push_back((node){i, w});
            }
            dfs1(1, 0);
            dfs2(1, 0);
            for(int i = 1; i <= n; i++)
                cout << max(f[i][0], f[i][2]) << endl;
            init();
        }
        return 0;
    }
  • 相关阅读:
    闻彭水诗人醉酒攀岩写诗
    点滴记录:管理工作的50点亲身感悟(分享!)
    激发潜能 成就梦想:抱着积极的心态开发你的潜能
    成功者的十二项核心因素——最切实的成功法则
    free buffer waits等待事件
    latch: library cache pin等待事件
    ksfd: async disk IO等待事件
    latch:library cache lock等待事件
    library cache latch等待事件
    在Fedora 15上使用Vmware Server 2.0.2
  • 原文地址:https://www.cnblogs.com/BeyondLimits/p/11420309.html
Copyright © 2011-2022 走看看