zoukankan      html  css  js  c++  java
  • D

    You are given a tree that represents a hierarchy in a company, where the parent of node u is their direct manager.

    Each employee is assigned a project, and multiple employees can be assigned to the same project. When it is time for the presentation of the ith project, all employees u that are assigned that project and their direct and indirect managers must attend the presentation (u and their manager and their manager's manager and so on until the CEO).

    Find for each project the number of people attending its presentation.


    Input

    The first line of input is n and m (1 ≤ m ≤ n ≤ 106), the number of employees and the number of projects, respectively.

    The second line of input contains n integers ai (1 ≤ ai ≤ m), where ai is the project assigned to the ith employee. It is guaranteed that each project has at least one employee assigned to it.

    The third line of input contains n integers pi (0 ≤ pi ≤ n), where pi is the direct manager of the ith employee. If pi = 0, then the ith employee is the CEO and does not have a manager. It is guaranteed that there is only one CEO, and this CEO is a direct or indirect manager of all other employees.

    Output

    Output m integers, where the ith integer is the number of people attending the presentation of the ith project.

    Example
    Input
    6 4
    1 2 4 3 2 4
    0 1 1 3 3 2
    
    Output
    1 4 3 4 
    题解:首先根据题意建树,每个节点有对应的任务(1~m),如果一个人处理i任务,那么他所有的祖先都得参与到当中,对于每一个任务,求参与到其中的人的数量。
    首先DFS序跑图,得到每个节点的入时间序,时间序对应的原节点,深度,走2^0步得到的节点。
    然后对于每一个任务:假设其中有x个人执行这个任务,我们首先将其按DFS序从小到大排序,然后有对应公式:sum+=dep[i]-dep[LCA(i-1,i)]。
    那么就该想如何实现这个过程了,下面是用的vector存储:
    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int maxn=1000100;
    int w[maxn],x,root,cnt;
    int Start[maxn],End[maxn],dep[maxn],par[24][maxn],Rev[maxn];
    vector<int>G[maxn],vv[maxn],ans;
    void DFS(int u,int pre,int d)
    {
        par[0][u]=pre;//u向上走2^0走到pre节点
        dep[u]=d;//u的深度
        Start[u]=++cnt;//DFS序对应值
        Rev[cnt]=u;//将其反过来转换为原来的节点
        for(int i=0;i<G[u].size();i++){
            DFS(G[u][i],u,d+1);
        }
        End[u]=cnt;
    }
    int LCA(int u,int v)
    {
        if(dep[u]>dep[v])swap(u,v);
        for(int k=0;k<20;k++){//让u和v走到同一深度
            if((dep[v]-dep[u])>>k&1){//这里简单理解下就是将u和v的距离用二进制表示,每一位1将其变为0
                v=par[k][v];
            }
        }
        if(u==v)return u;
        for(int k=19;k>=0;k--){
            if(par[k][u]!=par[k][v]){
                u=par[k][u];
                v=par[k][v];
            }
        }
        return par[0][u];
    }
    int main()
    {
        ios::sync_with_stdio(0);
        int n,m;
        cin>>n>>m;
        for(int i=1;i<=n;i++)cin>>w[i];
        for(int i=1;i<=n;i++){
            cin>>x;
            if(x!=0){
                G[x].push_back(i);
            }
            else
                root=i;
        }
        DFS(root,-1,1);
        for(int k=0;k<20;k++){//预处理par数组
            for(int v=1;v<=n;v++){
                if(par[k][v]==-1)par[k+1][v]=-1;
                else par[k+1][v]=par[k][par[k][v]];
            }
        }
        for(int i=1;i<=n;i++){
            vv[w[i]].push_back(Start[i]);
        }
        for(int i=1;i<=m;i++){
            sort(vv[i].begin(),vv[i].end());//按照DFS序递增排序,是为了不重复答案
            int sum=0;
            for(int j=0;j<vv[i].size();j++){
                if(j==0)sum+=dep[Rev[vv[i][j]]];
                else sum+=dep[Rev[vv[i][j]]]-dep[LCA(Rev[vv[i][j-1]],Rev[vv[i][j]])];
            }
            ans.push_back(sum);
        }
        for(int i=0;i<ans.size();i++)cout<<ans[i]<<" ";
        cout<<endl;
        return 0;
    }
  • 相关阅读:
    dubbo监控报错Error creating bean with name 'uriBrokerService'
    Mysql批量导入约束报错
    Spring+Mybatis+Dubbo报错java.lang.reflect.MalformedParameterizedTypeException
    group by查询每组时间最新的一条记录
    Ztree
    朴素贝叶斯算法原理小结
    SimRank协同过滤推荐算法
    用Spark学习矩阵分解推荐算法
    XGBoost算法原理小结
    集成学习之Adaboost算法原理小结
  • 原文地址:https://www.cnblogs.com/cherish-lin/p/11104797.html
Copyright © 2011-2022 走看看