2022-03-21 23:04阅读: 44评论: 1推荐: 0

模拟 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 中国大陆许可协议进行许可。

posted @   TimMCBen  阅读(44)  评论(1编辑  收藏  举报
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起
  1. 1 404 not found REOL
404 not found - REOL
00:00 / 00:00
An audio error has occurred.