校内胡策 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;
}

原文地址:https://www.cnblogs.com/zwfymqz/p/9096743.html

时间: 2024-07-31 07:35:35

校内胡策 T9270 mjt树的相关文章

校内胡策(唯一一个想出来的)

2 第一题 (third.cpp/c/pas) 题目描述 小 R 最近沉迷于一个叫做 Slay.one 的游戏. 在这个游戏中,每一局有若干人参加,最终会产生一个优胜者.优胜者会获得 一个成就点. 现在小 R 已经利用某种手段得知了每场游戏有哪些人参加.假设所有人最初成 就点都是 0 ,小 R 想要知道所有游戏结束之后成就点最多的人至少有多少成就点. 校内胡策(唯一一个想出来的) 原文地址:https://www.cnblogs.com/Lance1ot/p/9445468.html

校内胡策 agar - BFS

problem 2 agar(agar.cpp)题目描述Skyfall 最近迷上了一个叫做 agar 的游戏.在这个游戏中,地图由 N*M 的点阵构成,每个 cell占有一个点.体积大的 cell 可以吃掉体积小的 cell,吃掉之后,较大的 cell 的大小会增加被吃掉的 cell 的大小.比如:你的大小为 3,吃掉了一个大小为 2 的 cell 之后你的大小变为 5.现在,地图上有 T 个细胞,第 i 个细胞的大小为 Qi,位置为 Xi,Yi .( 保 证 这 T 个 cell 坐标互不相同

校内胡策 埃罗芒阿老师 - 贪心 &amp; 堆 + EX难度 - DP

题目描述 埃罗芒阿老师是著名的插画家,她的工作是为电击文库出版的的书画插画.快要到截稿日了,埃罗芒阿老师还在水>_<埃罗芒阿突然发现自己还有一大堆插画没有完成,如果不能在截稿时间内完成是要扣工资的.于是埃罗芒阿老师把每个任务所需的时间和现在(0 时刻)距离每个任务截稿的时间记录了下来,想要计算出最多可以完成多少任务.输入描述 第一行是一个整数 N,接下来 N 行每行两个整数 T1,T2 描述一个任务:完成这个任务需要 T1 秒,如果在 T2 秒之内还没有完成任务,这个任务就到截稿时间了.输出描

【弱校胡策】2016.4.14 (bzoj2164)最短路+状压DP+矩阵乘法+高斯消元+树链剖分+线段树+背包DP

cyyz&qhyz&lwyz&gryz弱校胡策 命题人:cyyz ws_fqk T3暴力写挫了 50+10+0滚粗辣! 奇妙的约会(appointment.cpp/c/pas) [问题描述] DQS和sxb在网上结识后成为了非常好的朋友,并且都有着惊人 的OI水平.在NOI2333的比赛中,两人均拿到了金牌,并保送进入 HU/PKU.于是两人决定在这喜大普奔的时刻进行面基. NOI2333参赛选手众多,所以安排了n个考点,DQS在1号考点, 而sxb在n号考点.由于是举办全国性赛事

弱省胡策系列简要题解

现在不是非常爽,感觉智商掉没了,就整理一下最近弱省胡策的题目吧. 其实题目质量还是很高的. 如果实在看不懂官方题解,说不定这里bb的能给您一些帮助呢? [弱省胡策]Round #0 A 20%数据,O(n4)傻逼dp. 40%数据,O(n3)傻逼dp. 100%数据,令f(x1,y1,x2,y2)表示从(x1,y1)走到(x2,y2)的路径条数.于是所有路径就是f(1,2,n?1,m)×f(2,1,n,m?1).然而两条路径可能在中间的某个点相交,我们找出最早的交点,并在这个交点互换两条路径的后

山西胡策 #6

A. 题意:求去掉d物品后容量为e最大背包.每个物品有三种属性,权值.容量.数量. #include <bits/stdc++.h> using namespace std; const int V=1000, N=1005; void zop(int *d, int w, int v) { for(int i=V; i>=v; --i) d[i]=max(d[i], d[i-v]+w); } void cmp(int *d, int w, int v) { for(int i=v; i

山西胡策 #7

A. B. C. 题意:给出(i, j)之类的约束表示要j必须先i,问1尽量靠前.2尽量靠前.3尽量靠前以此类推的最优方案,或输出无解. #include <bits/stdc++.h> using namespace std; const int N=100005; int cnt, ihead[N], in[N], ans[N], tot, n, m; struct E { int next, to; }e[N]; void add(int x, int y) { e[++cnt]=(E)

STOI补番队胡策

#1 第一轮是我出的. 比赛情况: #1 NanoApe 300 (完美AK) #2 && #3 swm_sxt / ccz  200 A.candy 这道题就是个nim游戏, 我们知道当且仅当选出的各堆糖果的异或和为0时,先手必败. 这样问题转化为从N个数中选1一些数使得他们的异或和为0的方案数. 30%,O(2^N) DFS. 假如只有询问, 那么可以直接用类似01背包的dp解决. for i = 1 ~ 1024 dp(i, x) += dp(i-1, x^w_i); dp(i, x

【弱省胡策】Round #7 Rectangle 解题报告

orz PoPoQQQ 的神题. 我的想法是:给每一个高度都维护一个 $01$ 序列,大概就是维护一个 $Map[i][j]$ 的矩阵,然后 $Map[i][j]$ 表示第 $i$ 根柱子的高度是否 $\ge j$. 那么怎么维护 $Map[i][j]$ 呢..? 首先我们把柱子按照高度从小到大排序,然后依次给每个高度建主席树,初始时 $Map[i][0]$ 全是 $1$,然后如果当前高度 $i$ 比某个柱子 $j$ 的高度要大了,那么就单点修改 $Map[i][j]$,然后这个就是主席树动态开