专栏文章

别样的碰碰车大战题解

题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mioq0zfo
此快照首次捕获于
2025/12/02 23:16
3 个月前
此快照最后确认于
2025/12/02 23:16
3 个月前
查看原文

别样的碰碰车大战

太典了
不是我说,这几乎就是树型DP板子题吧

20pts

枚举每一个点选/不选,再统计答案
时间复杂度 O(2NN)O(2^NN)

100pts

考虑树型DP
f[u][0/1]f[u][0/1] 表示以 uu 为根的子树中, uu 不选/选的最大边权和
很明显:如果不选 uu ,那么连接 uu 和其子结点的边就不会被选中。因此最大值为:
vsonumax(f[v][0],f[v][1])\sum_{v\in son_u}\max(f[v][0],f[v][1])
如果选 uu ,那么当其子节点也被选中时,就会获得该边边权,因此最大值为:
vsonumax(f[v][0],f[v][1]+w)\sum_{v\in son_u}\max(f[v][0],f[v][1]+w)
其中 ww 为连接 uuvv 的边的边权

Code

CPP
#include<bits/stdc++.h>
namespace Kards{
	using namespace std;
	typedef long long ll;
	ll n,f[100005][2];
	vector<pair<ll,ll> >a[100005];
	void dfs(ll x,ll fa){
		for(auto [v,w]:a[x]){
			if(v==fa)continue;
			dfs(v,x);
			f[x][0]+=max(f[v][0],max(f[v][1],0ll));
			f[x][1]+=max(f[v][0],max(f[v][1]+w,0ll));
		}
	}
	int main(){
		ios::sync_with_stdio(0);
		cin.tie(nullptr);
		cout.tie(nullptr);
		cin>>n;
		for(int i=1,u,v,w;i<n;i++){
			cin>>u>>v>>w;
			a[u].emplace_back(v,w);
			a[v].emplace_back(u,w);
		}
		dfs(1,0);
		cout<<max(f[1][0],f[1][1]);
		return 0;
	}
}
int main(){return Kards::main();}

注意:

  • long long
  • 由于可以不选,因此DP时要与0取最大值

评论

0 条评论,欢迎与作者交流。

正在加载评论...