T9270 mjt树

题目背景

从前森林里有一棵很大的mjt树,树上有很多小动物。

题目描述

mjt树上有 n 个房间,第 i 个房间住着 ai 只第bi 种小动物。
这n个房间用n-1条路连接起来,其中房间1位mjt树的根。
现在每个房间x的小动物想知道,以房间x为根的mjt树中有多少只它们的同类.
输入输出格式

输入格式:
第一行一个整数n,表示房间数

接下来n行,每行两个整数ai,bi

再之后n-1,每行两个整数x、y,表示x和y之间有一条路径

输出格式:
一行n个数,第i个数表示以房间i为根的mjt树中bi种小动物有多少只,两个数之间用空格隔开

输入输出样例

输入样例#1: 复制
5
2 1
3 1
4 2
5 1
6 2
1 2
1 3
3 4
3 5
输出样例#1: 复制
10 3 10 5 6
说明

bi<=n<=100000,ai<=1000

by xjjppm.

dfs,把他的之前遍历的该编号的数+上子树的减去进入该节点之前遍历的

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int maxn =200007;
struct T{
	int a,b;
}tree[maxn];
struct node{
	int v,next;
}edge[maxn];
int n,num=0,head[maxn],sum[maxn];
void add_edge(int a,int b) {
	edge[++num].v=b;edge[num].next=head[a];head[a]=num;
}
int size[maxn],ans[maxn];

void dfs(int x,int f) {
	ans[x]=size[tree[x].b];
	size[tree[x].b]+=tree[x].a;
	for(int i=head[x];i;i=edge[i].next) {
		int v=edge[i].v;
		if(v!=f) dfs(v,x);
	}
	ans[x]=size[tree[x].b]-ans[x];
}
int main() {
	scanf("%d",&n);
	for(int i=1;i<=n;++i) {
		scanf("%d%d",&tree[i].a,&tree[i].b);
	}
	for(int a,b,j=1;j<n;++j) {
		scanf("%d%d",&a,&b);
		add_edge(a,b);
		add_edge(b,a);
	}
	dfs(1,0);
	for(int i=1;i<=n;i++) {
		printf("%d ",ans[i]);
	}
	return 0;
}
原文地址:https://www.cnblogs.com/sssy/p/7739396.html