标签:push htm src space child str sizeof 苹果 mat
二叉苹果树
第一行两个数N和Q,N表示树的节点数,Q表示要保留的树枝数量。
接下来N-1行描述树枝信息,每行三个整数,前两个是它连接的节点的编号,第三个数是这根树枝上苹果数量。
输出仅一行,表示最多能留住的苹果的数量。
5 2 1 3 1 1 4 10 2 3 20 3 5 20
21
对于100%的数据,1≤Q≤N≤100,N≠11,每根树枝上苹果不超过30000个。
题目思路:
f[i][j]表示以i为根节点的子树保留j根树枝的最多苹果数,d[i][j]表示i节点到j节点树枝上的苹果数。
vector作为邻接表记录与每个节点相邻的节点(注意dfs时不能走父节点)。
代码如下(记忆化搜索实现):
#include<bits/stdc++.h> #define ll long long using namespace std; int n,m,f[101][101],d[101][101]; vector<int> v[101]; int dfs(int x,int y,int fa) { vector<int> child; int ans = 0; if(f[x][y]!=-1) return f[x][y]; if(x!=1&&v[x].size()==1||y==0) { f[x][y] = ans; return ans; } else if(v[x].size()==2&&x!=1||x==1&&v[x].size()==1) { for(int i = 0;i<v[x].size();i++) if(v[x][i]!=fa) child.push_back(v[x][i]); ans = d[x][child[0]]+dfs(child[0],y-1,x); f[x][y] = ans; return ans; } else { for(int i = 0;i<v[x].size();i++) if(v[x][i]!=fa) child.push_back(v[x][i]); if(y>=2) for(int i = 0;i<y-1;i++) ans = max(ans,d[x][child[0]]+d[x][child[1]]+dfs(child[0],i,x)+dfs(child[1],y-i-2,x)); if(y>=1) { ans = max(ans,d[x][child[0]]+dfs(child[0],y-1,x)); ans = max(ans,d[x][child[1]]+dfs(child[1],y-1,x)); } f[x][y] = ans; return ans; } } int main() { memset(d,-1,sizeof(d)); memset(f,-1,sizeof(f)); int a,b,c; cin>>n>>m; for(int i = 0;i<n-1;i++) { cin>>a>>b>>c; v[a].push_back(b); v[b].push_back(a); d[a][b] = c; d[b][a] = c; } cout<<dfs(1,m,0); return 0; }
如果有错误的地方,还请各位大佬指正。
标签:push htm src space child str sizeof 苹果 mat
原文地址:https://www.cnblogs.com/loganacmer/p/11296870.html