模拟 Enterprise Recognition Program
这题是离线,相对好模拟
题意:
一个公司的管理为树状结构
有两种发放钱的方式。
- 单个人的奖金
- 对单个人以及所有上级发放奖金
有两个询问的方式 - 询问单个人的奖金
- 询问下属的奖金加上自己的奖金
思路:
用一个二维数组earn[N][3]来储存 第一种方式获得的、第二种方式得到的(用于向上继承)、下属的奖金
用树结构储存完后,dfs搜索一遍节点,更新earn[][1]和earn[][2].
(https://img2022.cnblogs.com/blog/2781289/202203/2781289-20220322083927614-1386639216.png)
#include<bits/stdc++.h> using namespace std; const int N = 1e6+7; using ll = long long; ll earn[N][3]; #define IOS ios::sync_with_stdio(false),cin.tie(0); struct edge{ int next; //储存相同节点的边的序号便于遍历 int to; }edge[N]; int num_edge; int head[N]; void pre() { memset(head,-1,sizeof head); } void add_edge(int from,int to) { edge[num_edge].next=head[from]; //第一次执行时候 为 -1 ,呼应 dfs的条件 edge[num_edge].to=to; head[from]=num_edge++; //这里的是以每个节点的第一个子节点为尾巴,其他的子节点逐一添在尾巴后面. } void dfs(int u) //从右往左遍历每个节点的子节点 { for(int i=head[u];i!=-1;i=edge[i].next) { int v = edge[i].to; dfs(v); earn[u][1]+=earn[v][1];//奖金方式分配的,继承子节点的奖金 earn[u][2]+=earn[v][0]+earn[v][1]+earn[v][2];//储存 unit的总奖金 自己赚的+分配的+unit的; } } signed main() { IOS; pre(); int n,m,q; int boss; cin>>n>>m>>q; for(int i=1;i<=n;i++) { int num; cin>>num; add_edge(num,i); if(num==0) { boss=i; } } int t,v,e; for(int i=1;i<=m;i++) { cin>>t>>v>>e; if(t==1) { earn[v][0]+=e; }else { earn[v][1]+=e; } } dfs(boss); for(int i=1;i<=q;i++) { cin>>t>>e; if(t==1) { cout<<earn[e][0]+earn[e][1]<<endl; }else { cout<<earn[e][2]+earn[e][1]+earn[e][0]<<endl; } } }
本文作者:TimMCBen
本文链接:https://www.cnblogs.com/TimMCBen/p/16037214.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步