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,,wnwi denotes the weight of the node i.

The following (n1) 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.

(1n2103,1wi105)

Output

n integers c1,c2,,cnci 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?'
':' ');
    }
    return 0;
}

  

原文地址:https://www.cnblogs.com/water-full/p/4511089.html