Codeforce 1800Difficulty Graphs 20 questions

1.CF1324F Maximum White Subtree

给定一棵 n n n 个节点无根树,每个节点 u u u 有一个颜色 a u a_u au,若 a u a_u au 0 0 0 u u u 是黑点,若 a u a_u au 1 1 1 u u u 是白点。

  • 对于每个节点 u u u,选出一个包含 u u u 的连通子图,设子图中白点个数为 c n t 1 cnt_1 cnt1,黑点个数为 c n t 2 cnt_2 cnt2,请最大化 c n t 1 − c n t 2 cnt_1 - cnt_2 cnt1cnt2。并输出这个值。
  • 1 ≤ n ≤ 2 × 1 0 5 1 \leq n \leq 2 \times 10^5 1n2×105 0 ≤ a u ≤ 1 0 \leq a_u \leq 1 0au1

思路:

换根dp

第一次dfs,先用1做根预处理出每个点的子树中最大的cnt1-cnt2(自底向上)

第二次dfs,对于每一个子树
若该子树的size>0,则有两种选择,一种是只选择这棵子树,二是选择整棵树

若该子树size<0,可以选择这棵子树或者选择整棵树,因为父亲树是不包括它的,所以要父亲树加上这棵子树

#include<bits/stdc++.h>
using namespace std;
constexpr int maxn=2e5+5,inf=0x3f3f3f3f;
int n,m,k,t,cnt,tt;
int size[maxn];
vector<int>e[maxn];
void dfs1(int u,int fa){
	for(auto v:e[u]){
		if(v==fa)continue;
		dfs1(v,u);
		if(size[v]>0)size[u]+=size[v];
	}
}
void dfs2(int u,int fa){
	for(auto v:e[u]){
		if(v==fa)continue;
		if(size[v]>0){
			size[v]=max(size[v],size[u]);
		}
		else{
			size[v]=max(size[v],size[u]+size[v]);
		}
		dfs2(v,u);
	}
}
int main(){
	cin>>n;
	int flag=0;
	for(int i=1;i<=n;i++){
		cin>>size[i];
		if(!size[i])size[i]=-1;
	}
	for(int i=1;i<=n-1;i++){
		int u,v;
		cin>>u>>v;
		e[u].push_back(v);
		e[v].push_back(u);
	}
	dfs1(1,1);
	dfs2(1,1);
	for(int i=1;i<=n;i++){
		printf("%d ",size[i]);
	}
}

咕了

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值