[POJ 3585] Accumulation Degree

[题目链接]    

        http://poj.org/problem?id=3585

[算法]

        树形DP——二次扫描与换根法

[代码]

       

#include <algorithm>  
#include <bitset>  
#include <cctype>  
#include <cerrno>  
#include <clocale>  
#include <cmath>  
#include <complex>  
#include <cstdio>  
#include <cstdlib>  
#include <cstring>  
#include <ctime>  
#include <deque>  
#include <exception>  
#include <fstream>  
#include <functional>  
#include <limits>  
#include <list>  
#include <map>  
#include <iomanip>  
#include <ios>  
#include <iosfwd>  
#include <iostream>  
#include <istream>  
#include <ostream>  
#include <queue>  
#include <set>  
#include <sstream>  
#include <stdexcept>  
#include <streambuf>  
#include <string>  
#include <utility>  
#include <vector>  
#include <cwchar>  
#include <cwctype>  
#include <stack>  
#include <limits.h> 
using namespace std;
#define MAXN 200010

int i,n,tot,u,v,w,ans,T;
int d[MAXN],f[MAXN],degree[MAXN],head[MAXN];

struct Edge
{
    int to,w,nxt;
} e[MAXN<<1];

inline void addedge(int u,int v,int w)
{
    tot++;
    e[tot] = (Edge){v,w,head[u]};
    head[u] = tot;
}
inline void dp(int u,int fa)
{
    int i,v,w;
    d[u] = 0;
    for (i = head[u]; i; i = e[i].nxt)
    {
        v = e[i].to;
        w = e[i].w;
        if (fa != v)
        {
            dp(v,u);
            if (degree[v] == 1) d[u] += w;
            else d[u] += min(d[v],w);
        }
    }
}
inline void dfs(int u,int fa)
{
    int i,v,w;
    for (i = head[u]; i; i = e[i].nxt)
    {
        v = e[i].to;
        w = e[i].w;
        if (fa != v)
        {
            if (degree[u] == 1) f[v] = d[v] + w;
            else f[v] = d[v] + min(f[u] - min(d[v],w),w);
            dfs(v,u);
        }
    }    
}

int main()
{
    
    scanf("%d",&T);
    while (T--)
    {
        scanf("%d",&n);
        tot = 0;
        for (i = 1; i <= n; i++) 
        {
            head[i] = 0;
            degree[i] = 0;
            d[i] = 0;
            f[i] = 0;
        }
        for (i = 1; i < n; i++)
        {
            scanf("%d%d%d",&u,&v,&w);
            addedge(u,v,w);
            addedge(v,u,w);
            degree[u]++;
            degree[v]++;
        }
        dp(1,-1);
        f[1] = d[1];
        dfs(1,-1);
        ans = 0;
        for (i = 1; i <= n; i++) ans = max(ans,f[i]);
        printf("%d\n",ans);
    }

    return 0;
}

 

posted @ 2018-07-18 18:25  evenbao  阅读(138)  评论(0编辑  收藏  举报