[树] cf1324F

题目

在这里插入图片描述
题目链接:https://codeforces.com/contest/1324/problem/F

思路

把树都看成一块一块的~
先用第一个dfs跑出这个数所在的这一块最多由多少个,每一个的值由他周围的的最大值决定的,这部相当于预处理最大值,用val存最大值。
在用一个dfs跑一下这个数和相邻的看看可不可以再多,用ans存结果。
最开始要先处理一下输入,把输入的0变成-1方便计算

代码

#include<cstdio>
#include<cstring>
#include<cmath>
#include<cstdlib>
#include<cctype>
#include<ctime>
#include<iostream>
#include<string>
#include<map>
#include<queue>
#include<stack>
#include<set>
#include<vector>
#include<iomanip>
#include<list>
#include<bitset>
#include<sstream>
#include<fstream>
#include<complex>
#include<algorithm>
#if __cplusplus >= 201103L
#include <unordered_map>
#include <unordered_set>
#endif
#define ll long long
using namespace std;
const int INF = 0x3f3f3f3f;
struct sut{
	int to,next;
}edge[800010];
int head[200010],val[200010],ans[200010],tot=0,a[200010];
void add_edge(int u,int v){
	edge[++tot].to=v;
	edge[tot].next=head[u];
	head[u]=tot;
}
void dfs1(int f,int s){
//	cout<<s<<endl;
	val[s]=a[s];
	for(int i=head[s];i;i=edge[i].next){
		int v1=edge[i].to;
		if(v1==f) continue;//节点相同就不跑
		dfs1(s,v1);
		if(val[v1]>=0)val[s]+=val[v1];
		//cout<<val[s]<<" "<<s<<endl;
	}
}
void dfs2(int f,int s){
	ans[s]=val[s];
	if(val[s]>0) ans[f]-=ans[s];
	if(ans[f]>0) ans[s]+=ans[f];
	for(int i=head[s];i;i=edge[i].next){
		int v1=edge[i].to;
		if(v1==f) continue;
		dfs2(s,v1);
	}
	if(val[s]>0) ans[f]+=val[s];
}
int main(){
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	int n,t;
	cin>>n;
	t=n;
	for(int i=1;i<=n;i++) {
		cin>>a[i];
		if(a[i]==0) a[i]=-1;} 
	n--;
	memset(head,0,sizeof head);
	while(n--){
		int u,v;
		cin>>u>>v;
		add_edge(u,v);
		add_edge(v,u);
	}
	dfs1(0,1);
//	for(int i=1;i<=n;i++) cout<<<<i<<endl;
	dfs2(0,1);
	for(int i=1;i<=t;i++) cout<<ans[i]<<" \n"[i==n];
    return 0;
}

发布了78 篇原创文章 · 获赞 1 · 访问量 4369

猜你喜欢

转载自blog.csdn.net/kosf_/article/details/104852609
今日推荐