P3174 [HAOI2009] 毛毛虫
作者:互联网
非常好的一道树形dp 我开始一直陷入了思维误区
认为最优解可能不但是从子树转移过来还可能是从父亲转移过来的
这就非常头疼了 转移方程不好写啊
但实际上直接从下向上转移就好 为什么
因为最优解 保证一定存在一个节点 最优解为该节点最大子树和次大子树之和 最为极端的情况就是 最优解那个节点只有一个子树 但是一定保证该节点是存在的
所以转移的时候 我们只要判断每个节点并且跟新ans就好
dp[u] 表示所有u的子树的最大值
max1表示最大值 max2表示次大值
还要特别判断 根节点和叶节点 这俩点比较特殊
更新ans的时候别忘记了还有fa也可以算进毛毛虫里面
点击查看代码
#include<bits/stdc++.h>
using namespace std;
#define lowbit(x) x&(-x)
#define ll long long
const int maxn=3e6+5;
int n,m,ans;
vector<int>Q[maxn];
int dp[maxn];
void dfs(int u,int fa);
int main(){
cin>>n>>m;
for(int i=1,aa,bb;i<=m;i++){
cin>>aa>>bb;
Q[aa].push_back(bb);
Q[bb].push_back(aa);
}
dfs(1,-1);
cout<<ans<<endl;
return 0;
}
void dfs(int u,int fa){
int max1=0,max2=0;
for(int i=0;i<Q[u].size();i++){
int to=Q[u][i];
if(to==fa)continue;
dfs(to,u);
dp[u]=max(dp[to],dp[u]);
if(dp[to]>=max1){
max2=max1;
max1=dp[to];
}
else if(dp[to]>=max2)
max2=dp[to];
}
int cnt=Q[u].size()-1;
if(fa==-1)cnt++;
if(!cnt)
dp[u]=1;
else dp[u]+=cnt;
if(cnt)
ans=max(ans,max1+max2+cnt+1+(fa!=-1)-(max1!=0)-(max2!=0));
}
标签:cnt,int,max1,P3174,max2,HAOI2009,毛毛虫,节点,dp 来源: https://www.cnblogs.com/wzxbeliever/p/16081175.html