zoukankan      html  css  js  c++  java
  • 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;
    }
    
  • 相关阅读:
    POJ 1185 炮兵阵地 经典的 状态压缩dp
    hdu 1565 方格取数(1) 状态压缩dp
    poj Corn Fields 状态压缩dp。
    fzu 2138 久违的月赛之一 容斥。
    fzu 2136 取糖果 好几种方法解决。
    hdu 1231 最大连续子序列
    选择排序
    SharedPrefernces使用实例讲解
    SharedPrefernces使用实例讲解
    可以ping通,但是不能connect
  • 原文地址:https://www.cnblogs.com/sssy/p/7739396.html
Copyright © 2011-2022 走看看