标签:
Given a tree with weight assigned to nodes, find out minimum total weight connected component with fixed number of node.
The first line contains a single integer n.
The second line contains n integers $w_1,w_2,…,w_n. w_i$ 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\leq n\leq 2⋅10^3,1\leq w_i\leq 10^5)$
$n$ integers $c_1,c_2,…,c_n. c_i$ stands for the minimum total weight component with i nodes.
3 1 2 3 1 2 2 3
1 3 6
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int maxn = 2010; 4 vector<int>g[maxn]; 5 int val[maxn],dp[maxn][maxn],n,son[maxn],ans[maxn]; 6 void dfs(int u,int fa){ 7 dp[u][1] = val[u]; 8 dp[u][0] = 0; 9 son[u] = 1; 10 for(int i = g[u].size()-1; i >= 0; --i){ 11 if(g[u][i] == fa) continue; 12 dfs(g[u][i],u); 13 son[u] += son[g[u][i]]; 14 for(int j = son[u]; j > 0; --j){ 15 for(int k = 1; k <= j; ++k) 16 dp[u][j] = min(dp[u][j],dp[g[u][i]][j - k] + dp[u][k]); 17 } 18 } 19 for(int i = son[u]; i >= 0; --i) 20 ans[i] = min(ans[i],dp[u][i]); 21 } 22 int main(){ 23 while(~scanf("%d",&n)){ 24 for(int i = 0; i < maxn; ++i) g[i].clear(); 25 for(int i = 1; i <= n; ++i) scanf("%d",val + i); 26 memset(dp,0x3f,sizeof dp); 27 memset(ans,0x3f,sizeof ans); 28 for(int i = 1,u,v; i < n; ++i){ 29 scanf("%d%d",&u,&v); 30 g[u].push_back(v); 31 g[v].push_back(u); 32 } 33 dfs(1,-1); 34 for(int i = 1; i <= n; ++i) 35 printf("%d%c",ans[i],i == n?‘\n‘:‘ ‘); 36 } 37 return 0; 38 }
标签:
原文地址:http://www.cnblogs.com/crackpotisback/p/4816582.html