acdream 1032

Component

Time Limit: 10000/5000MS (Java/Others) Memory Limit: 128000/64000KB (Java/Others)

Problem Description

Given a tree with weight assigned to nodes, find out minimum total weight connected component with fixed number of node.

Input

The first line contains a single integer n.

The second line contains n integers w1,w2,…,wn. wi denotes the weight of the node i.

The following (n−1) lines with two integers ai and bi, which denote the edge between ai and bi.

Note that the nodes are labled by 1,2,…,n.

(1≤n≤2⋅103,1≤wi≤105)

Output

n integers c1,c2,…,cn. ci stands for the minimum total weight component with i nodes.

Sample Input

3 
1 2 3
1 2
2 3 

Sample Output

1 3 6 

Source

ftiasch

Manager

 
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<algorithm>
#include<string>
#include<vector>
using namespace std;
vector<int> e[2005];
int n,dp[2005][2005],val[2005],f[2005],siz[2005];
void dfs(int u,int father)
{
    memset(dp[u],63,sizeof(dp[u]));
    dp[u][1]=val[u];
    siz[u]=1;
    for(int i=0;i<e[u].size();i++)
    {
        int v=e[u][i];
        if(v==father)
            continue;
        dfs(v,u);
        siz[u]+=siz[v];
        for(int j=siz[u];j>=2;j--)
        {
            for(int k=min(siz[v],j-1);k>=1;k--)
            {
                dp[u][j]=min(dp[u][j],dp[u][j-k]+dp[v][k]);
            }
        }
    }
    for(int i=1;i<=siz[u];i++)
        f[i]=min(f[i],dp[u][i]);
}
int main()
{
    scanf("%d",&n);
    memset(f,63,sizeof(f));
    for(int i=1;i<=n;i++)
        scanf("%d",&val[i]);
    for(int i=1;i<n;i++)
    {
        int x,y;
        scanf("%d%d",&x,&y);
        e[x].push_back(y);
        e[y].push_back(x);
    }
    dfs(1,-1);
    for(int i=1;i<=n;i++)
    {
        printf("%d%c",f[i],i==n?'\n':' ');
    }
    return 0;
}

  

posted @ 2015-05-18 09:19  waterfull  阅读(186)  评论(0)    收藏  举报