GYM 101128 A.Promotions【思维+暴力】

来源:互联网 发布:北京生活软件 编辑:程序博客网 时间:2024/05/17 12:53



题目大意:

我们现在有E个员工,有P个关系,每个关系x,y表示x想要升级的话,y必须先升级。

问此时:

①如果我们希望A个人升级的话,必须需要升级的人数。

②如果我们希望B个人升级的话,必须需要升级的人数。

③如果我们希望B个人升级的话,有多少人一定升级不了。


思路:


设定三个要求的值为ansa,ansb,ansc;


①我们反向建图,然后O(n^2)去跑出ned【i】【j】,ned【i】【j】表示升级i之前,是否需要先升级j,如果需要,ned【i】【j】=1;


②然后我们很容易能够考虑到ansc的求法,我们再维护一个数组need【i】,表示升级i之前,必须需要升级的人数,那么如果有:need【i】>=B,也就是说我们要升级i这个人时候,需要之前先升级至少B个人才能升级这个人,那么这个人一定升级不了,那么ansc=Σneed【i 】>=B?1:0


③那么我们稍微考虑一下也不难想到,我们再维护一个数组nott【i】,表示升级了i之前,最多可以升级的人数,那么如果有nott【i】<A,那么ansa++,同理如果有nott【i】<B,那么ansb++.


过程维护一下,注意初始化就没别的什么了。。


Ac代码:

#include<stdio.h>#include<string.h>#include<iostream>#include<vector>using namespace std;int vis[5005];int need[5005];int nott[5005];vector<int>mp[5005];int ned[5005][5005];int A,B,n,m;void Dfs(int u,int root){    ned[root][u]=1;    for(int i=0;i<mp[u].size();i++)    {        int v=mp[u][i];        if(vis[v]==0)        {            vis[v]=1;            Dfs(v,root);        }    }}int main(){    while(~scanf("%d%d%d%d",&A,&B,&n,&m))    {        memset(nott,0,sizeof(nott));        memset(ned,0,sizeof(ned));        memset(need,0,sizeof(need));        for(int i=1;i<=n;i++)mp[i].clear();        for(int i=1;i<=m;i++)        {            int x,y;            scanf("%d%d",&x,&y);            x++;y++;            mp[y].push_back(x);        }        for(int i=1;i<=n;i++)        {            memset(vis,0,sizeof(vis));            Dfs(i,i);        }        int ansa,ansb,ansc;        ansa=ansb=ansc=0;        for(int i=1;i<=n;i++)        {            for(int j=1;j<=n;j++)            {                if(i==j)continue;                if(ned[i][j]==1)                {                    need[i]++;                }            }        }        for(int i=1;i<=n;i++)        {            for(int j=1;j<=n;j++)            {                if(i==j)continue;                if(ned[i][j]==0)                {                    nott[j]++;                }            }        }        for(int i=1;i<=n;i++)        {            if(nott[i]<A)ansa++;            if(nott[i]<B)ansb++;            if(need[i]>=B)ansc++;        }        printf("%d\n%d\n%d\n",ansa,ansb,ansc);    }}/*3 4 7 80 41 21 55 26 40 12 34 5*/