Gym - 101128A(dfs)

當成拓撲寫了,少了很多情況
維護一下當前這個人控制的人數 = 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
 */
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章