欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

校内胡策 T9270 mjt树

程序员文章站 2022-07-02 13:56:35
题目背景 从前森林里有一棵很大的mjt树,树上有很多小动物。 题目描述 mjt树上有 n 个房间,第 i 个房间住着 ai 只第bi 种小动物。 这n个房间用n-1条路连接起来,其中房间1位mjt树的根。 现在每个房间x的小动物想知道,以房间x为根的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 太强了orz。

 

// luogu-judger-enable-o2
// luogu-judger-enable-o2
#include<cstdio>
#include<cstring>
#include<vector>
#include<queue>
#define getchar() (p1 == p2 && (p2 = (p1 = buf) + fread(buf, 1, 1 << 21, stdin), p1 == p2) ? EOF : *p1++)
char buf[1 << 21], *p1 = buf, *p2 = buf;
//#define int long long 
using namespace std;
const int MAXN = 2 * 1e5 + 10;
inline int read() {
    char c = getchar(); int x = 0, f = 1;
    while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
    while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
    return x * f;
}
struct Edge {
    int u, v, nxt;
}E[MAXN];
int head[MAXN], num = 0;
inline void AddEdge(int x, int y) {
    E[num] = (Edge){x, y, head[x]};
    head[x] = num++;
}
int N, a[MAXN], b[MAXN], ans[MAXN], inder[MAXN], pre[MAXN];
vector<int>v[MAXN];
void dfs(int x, int fa) {    
    for(int i = head[x]; i != -1; i = E[i].nxt) {
        if(E[i].v == fa) continue;
        if(pre[b[E[i].v]]) 
            v[E[i].v].push_back(pre[b[E[i].v]]), inder[pre[b[E[i].v]]]++;
        int gg = pre[b[E[i].v]];
        pre[b[E[i].v]] = E[i].v;
        dfs(E[i].v, x);
        pre[b[E[i].v]] = gg;
    }

}
void Topsort() {
    queue<int>q;
    for(int i = 1; i <= N; i++)
        if(!inder[i]) q.push(i);
    while(q.size() != 0) {
        int p = q.front(); q.pop();
        for(int i = 0; i < v[p].size(); i++) {
            a[v[p][i]] += a[p];
            inder[v[p][i]]--;
            if(!inder[v[p][i]]) q.push(v[p][i]);
        }
    }
}
main() {
    #ifdef WIN32
    freopen("a.in", "r", stdin);
    #endif
    memset(head, -1, sizeof(head));
    N = read();
    for(int i = 1; i <= N; i++) a[i] = read(), b[i] = read();
    for(int i = 1; i <= N - 1; i++) {
        int x = read(), y = read();
        AddEdge(x, y); AddEdge(y, x);
    }
    pre[b[1]] = 1;
    dfs(1, 0);    
    Topsort();
    for(int i = 1; i <= N; i++) 
        printf("%lld ", a[i]);
    return 0;
}