题目大意:
我们现在有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 8
0 4
1 2
1 5
5 2
6 4
0 1
2 3
4 5
*/