• Gym 101128A :Promotions (Southwestern Europe Regional Contest )


    题意

     一个公司里有E个员工P个上下级关系。这个公司有一种晋升制度。如果要晋升员工a,那么必须要先晋升a的所有领导。给出一个区间[A,B],如果要晋升A个员工,有哪些员工是一定会被晋升的?如果要晋升B个员工,有哪些员工是一定会被晋升的?如果晋升B个员工,有哪些员工是一定不会被晋升的?

    分析

    这个描述再加上那个样例的图片实在太TM像拓扑排序了啊!当时在场上写了个拓扑排序然后WA的很惨

    如果要晋升A个员工,哪些员工是一定会被晋升的?当这个员工的下属数量(包括他自己)大于n-A的时候,则必须晋升它

    那么对于每个员工跑dfs统计出它下属的数量就可以。

    如果要晋升B个员工,哪些员工是一定不会被晋升的?当这个员工的上司数量大于B的时候,它一定不会被晋升。那么把图反过来,再对每个员工跑一遍dfs就可以,方法和上面一样。

    代码如下:

     1     #include <cstdio>
     2     #include <algorithm>
     3     #include <cstring>
     4     #include <iostream>
     5     #include <vector>
     6     #include <queue>
     7     using namespace std;
     8     const int maxn=5000+10;
     9     const int maxm=20000+10;
    10     vector<int>G[3][maxn];
    11     int vis[maxn];
    12     int A,B,E,P;
    13     int a,b;
    14     int ansa,ansb,ansc;
    15     int num[maxn];
    16     void dfs(int n,int u,int o){
    17         vis[u]=1;
    18         num[o]++;
    19         for(int i=0;i<G[n][u].size();i++){
    20             int v=G[n][u][i];
    21             if(!vis[v])
    22             dfs(n,v,o);
    23         }
    24         return ;
    25     }
    26     int main(){
    27         ansa=ansb=ansc=0;
    28         scanf("%d%d%d%d",&A,&B,&E,&P);
    29         memset(num,0,sizeof(num));
    30         for(int i=1;i<=P;i++){
    31             scanf("%d%d",&a,&b);
    32             G[1][a].push_back(b);
    33             G[2][b].push_back(a);
    34         }
    35         for(int i=0;i<E;i++){
    36             memset(vis,0,sizeof(vis));
    37             dfs(1,i,i);
    38         }
    39         for(int i=0;i<E;i++){
    40             if(num[i]>E-A)ansa++;
    41             if(num[i]>E-B)ansb++;
    42         }
    43         memset(num,0,sizeof(num));
    44         for(int i=0;i<E;i++){
    45             memset(vis,0,sizeof(vis));
    46             dfs(2,i,i);
    47         }
    48 
    49         for(int i=0;i<E;i++){
    50             if(num[i]>B)ansc++;
    51         }
    52         cout<<ansa<<endl;
    53         cout<<ansb<<endl;
    54         cout<<ansc<<endl;
    55     return 0;
    56     }
    View Code

    另外当时想的拓扑排序为啥是错的呢,当时是觉得跑一遍拓扑排序然后找出每个拓扑顺序上员工的数量,然后由低到高加起来只要现在的数量不超过A。然后这就是一定会被晋升的人数。但是这个晋升关系和拓扑序是有区别的。就拿样例来说,如果要晋升两个员工,按照这种拓扑思想,0和6都是一定会被晋升的,因为他们的拓扑序都是第一个,但题目并不是这个意思,因为晋升了0以后,1也可以得到晋升了,那么晋升两个员工有可能晋升0和6,也可能晋升0和1,所以一定被晋升的只有0结点自己。

  • 相关阅读:
    java web分享ppt大纲 -- servlet容器简介
    Docker入门二
    Docker入门
    自动化运维
    堡垒机
    代码管理平台
    NoSQL(四)
    NoSQL(三)
    NoSQL(二)
    CentOS添加新网卡network-scripts目录下找不到网卡配置文件
  • 原文地址:https://www.cnblogs.com/LQLlulu/p/8818170.html
Copyright © 2020-2023  润新知