Gushing over Program|

BigSmall_En

园龄:3年2个月粉丝:3关注:5

2022-11-12 21:32阅读: 32评论: 0推荐: 0

LG3174 [HAOI2009] 毛毛虫 题解

LG3174 [HAOI2009] 毛毛虫

对于一棵树,我们可以将某条链和与该链相连的边抽出来,看上去就象成一个毛毛虫,点数越多,毛毛虫就越大。给定一棵树,求其最大的毛毛虫的大小。

容易发现毛毛虫的主干就是树上的一条链。

定义 \(dp_u\) 为一条从 \(u\) 开始往其子树延申的一条链,满足这条链组成的毛毛虫节点数最多的点数具体是多少(并且 \(u\) 点本身不算在这个点数中)。转移

\[dp_u=\max_{v\in son_u}dp_v+deg_u-1 \]

其中 \(deg_u\) 中包含了一条去 \(v\) 的边,填补了 \(dp_v\) 中不包含的 \(v\) 点。而 \(dp_v\) 中显然包含了 \(u\) 点,而 \(dp_u\) 的定义中是不包含 \(u\) 点的,所以 \(-1\)

统计答案:

\[ans\gets \max dp_{u}+1\\ ans\gets \max dp_u+dp_v\quad v\in son_u \]

\(dp_u,dp_v\) 中分别把对方的点填补上了。

想清楚后代码也就很好写了。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <vector>
#include <cmath>

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int>ttfa;
inline ll read(){
	ll x=0,f=1;char ch=getchar();
	while(ch<'0'||'9'<ch){if(ch=='-')f=-1;ch=getchar();}
	while('0'<=ch&&ch<='9'){x=(x<<3)+(x<<1)+(ch^48);ch=getchar();}
	return x*f;
}
const int N=1000006;
int n,m,deg[N],dp[N],fir[N],sec[N],ans;
vector<int>edge[N];
void dfs(int u,int f){
	dp[u]=deg[u];
	for(auto v:edge[u]){
		if(v==f)continue;
		dfs(v,u);
		ans=max(ans,dp[u]+dp[v]);
		dp[u]=max(dp[u],dp[v]+deg[u]-1);
	}
	ans=max(ans,dp[u]+1);
}
int main(){
	n=read(),m=read();
	for(int i=1;i<=m;++i){
		int u=read(),v=read();
		edge[u].push_back(v);
		edge[v].push_back(u);
		++deg[u],++deg[v];
	}
	dfs(1,0);
	printf("%d\n",ans);
	return 0;
}

本文作者:BigSmall_En

本文链接:https://www.cnblogs.com/BigSmall-En/p/16884731.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   BigSmall_En  阅读(32)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起