当成拓扑写了,少了很多情况
维护一下当前这个人控制的人数 = x,和选这个人需要选的人 = y,
那么对于某个人必选,就是这个人不选(控制的人也就不能选了),剩下的人不足a (b) ,就必选 n - x < a (b)
对于某个人不可能选中,就是选这个人需要的人y > b
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <set>
#include <cmath>
#include <map>
#include <sstream>
#define LL long long
#define INF 0x3f3f3f3f
#define mod 1000000007
#define eps 1e-8
const int maxn = 200000 + 5;
using namespace std;
vector<int> vec[maxn];
vector<int> vecc[maxn];
int vis[maxn];
int num[maxn];
int num2[maxn];
int dfs(int cur, int time){
if(vis[cur] == time) return 0;
vis[cur] = time;
int ans = 1;
for(int i=0; i<vec[cur].size(); i++){
ans += dfs(vec[cur][i],time);
}
return ans;
}
int dfs2(int cur, int time){
if(vis[cur] == time) return 0;
vis[cur] = time;
int ans = 1;
for(int i=0; i<vecc[cur].size(); i++){
ans += dfs2(vecc[cur][i], time);
}
return ans;
}
int main(){
int ans1 = 0, ans2 = 0, ans3 = 0;
int n,m,a,b;
scanf("%d%d%d%d",&a,&b,&n,&m);
for(int i=0; i<m; i++){
int u,v;
scanf("%d%d",&u,&v);
vec[u].push_back(v);
vecc[v].push_back(u);
}
memset(vis, -1, sizeof(vis));
for(int i=0; i<n; i++)
num[i] = dfs(i,i);//支配的人
for(int i=0; i<n; i++){
if(n-num[i] < a) ans1++;
if(n-num[i] < b) ans2++;
}
memset(vis, -1, sizeof(vis));
for(int i=0; i<n; i++)
num2[i] = dfs2(i,i);//选中自己需要选中的人
for(int i=0; i<n; i++){
if(num2[i] > b) ans3++;
}
printf("%d\n%d\n%d\n",ans1,ans2,ans3);
}
/*
3 4 7 8
0 4
1 2
1 5
5 2
6 4
0 1
2 3
4 5
*/