题目:
分析:每一个节点都可以当作树的根,至少保留该根最大值问题求解节点个数次。之前有天平题做过删除指定个数的。这个应该更简单了。
不过这样没法用dp,记忆化搜搜啊!:直接是纯暴力的:
#include<bits/stdc++.h>
using namespace std;
int m;
vector<vector<int> > vv;
int A[16005];
int B[16005];
long long D[16005];
long long f(int x)
{
B[x]=0;
D[x]=A[x];
for(int i=0;i<vv[x].size();i++)
{
if(B[vv[x][i]]==0) continue;
B[vv[x][i]]=0;
long long c=0;
D[x]+=max(f(vv[x][i]),c);
}
return D[x];
}
int main()
{
cin>>m;
for(int i=1;i<=m;i++) cin>>A[i];
vector<int> v;
for(int i=0;i<=m;i++)
{
vv.push_back(v);
}
for(int i=1;i<m;i++)
{
int a,b;
cin>>a>>b;
vv[a].push_back(b);
vv[b].push_back(a);
}
long long maxx=-1;
for(int i=1;i<=m;i++)
{
memset(B,-1,sizeof(B));
memset(D,-1,sizeof(D));
B[i]=0;
maxx=max(maxx,f(i));
}
cout<<maxx;
}
看着题解,突然想到,完全没必要啊,中间的过程就可以求出来了。很好!我描述不清,可以想通的。
每一个节点都可以当作树的根
#include<bits/stdc++.h>
using namespace std;
int m;
vector<vector<int> > vv;
int A[16005];
int B[16005];
long long D[16005];
long long maxx=-(1<<30);
long long f(int x)
{
B[x]=0;
D[x]=A[x];
for(int i=0;i<vv[x].size();i++)
{
if(B[vv[x][i]]==0) continue;
B[vv[x][i]]=0;
long long c=0;
D[x]+=max(f(vv[x][i]),c);
}
maxx=max(maxx,D[x]);
return D[x];
}
int main()
{
cin>>m;
for(int i=1;i<=m;i++) cin>>A[i];
vector<int> v;
for(int i=0;i<=m;i++)
{
vv.push_back(v);
}
for(int i=1;i<m;i++)
{
int a,b;
cin>>a>>b;
vv[a].push_back(b);
vv[b].push_back(a);
}
memset(B,-1,sizeof(B));
memset(D,-1,sizeof(D));
B[1]=0;
f(1);
cout<<maxx;
}