• 校内胡策 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 太强了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;
    }
  • 相关阅读:
    Git忽略规则.gitignore梳理
    makefile 系统脚本分析
    Kipmi0 占用CPU 100%
    kubectl检查组件健康状态异常处理
    Java 数组如何转成List集合
    用户控件中多控件自定义单击事件
    DevExpress启动窗体SplashScreen
    使用C#获取统计局行政区划代码
    解决mysqlclient模块安装问题
    com.aspose.words 类LoadOptions
  • 原文地址:https://www.cnblogs.com/zwfymqz/p/9096743.html
Copyright © 2020-2023  润新知