Zoj 3201 Tree of Tree
生活随笔
收集整理的這篇文章主要介紹了
Zoj 3201 Tree of Tree
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
樹樹
時間限制:?1秒??????內存限制:?32768?KB
你給一個樹的每個節點的權重,你需要找到這棵樹的指定大小的最大子樹。
樹定義?
樹是其中不包含任何周期的連通圖。
輸入
有在輸入多個測試用例。
每種情況下的第一行是兩個整數N(1?<=?N?<=?100),K(1?<=?K?<=?N),其中N是該樹的節點的數量,K是子樹的大小,其次通過與N的非負整數,其中第k個整數表示第k個節點的權重的行。接下來的N?-?1行描述了樹,每行有兩個整數這意味著在這兩個節點之間的邊緣。以上所有的指標都是零基礎,這是保證樹的描述是正確的。
產量
一行與對于每種情況,這是最大的子樹的總權重的單個整數。
樣例輸入
3?1
10?20?30
0?1
0?2
3?2
10?20?30
0?1
0?2
樣例輸出
30
40
樹型DP+背包問題!
f[i][j]表示以i為根結點有j個結點子樹的最大權值。
以下代碼僅供參考!
#include<iostream> #include<cstdio> #include<cstring> #include<vector> using namespace std; #define MAX 105 vector<int> adj[MAX]; int f[MAX][MAX],tot[MAX],weight[MAX]; int ans,K; int max(int a,int b) {return a>b?a:b; } int DFS(int u,int father) {tot[u]=1;int i,j,k,v;for(i=0;i<adj[u].size();i++){v=adj[u][i];if(v==father) // 如果又回到了父節點的情況continue;tot[u]+=DFS(v,u);}f[u][1]=weight[u];for(i=0;i<adj[u].size();i++){v=adj[u][i];if(v==father)continue;for(j=tot[u];j>=1;j--){for(k=0;k<j&&k<=tot[v];k++){f[u][j]=max(f[u][j],f[u][j-k]+f[v][k]);}}}if(tot[u]>=K)ans=max(ans,f[u][K]);return tot[u]; } int main() {int N,i,u,v;while(~scanf("%d%d",&N,&K)){for(i=0;i<N;i++){scanf("%d",&weight[i]);adj[i].clear();}for(i=1;i<N;i++){scanf("%d%d",&u,&v);adj[u].push_back(v);adj[v].push_back(u);}memset(f,0,sizeof(f));ans=0;DFS(1,-1);printf("%d\n",ans);}return 0; }總結
以上是生活随笔為你收集整理的Zoj 3201 Tree of Tree的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 阿里晓斌:如何做好技术 Team Lea
- 下一篇: 张一鸣:做CEO要避免理性的自负