zoukankan      html  css  js  c++  java
  • Gym 101128A Promotions(思维 + dfs)题解

    题意:给一有向图,如果A指向B,则A是B的上级。一直i要升职那么他的上级必须都升职。现在给你一个升职人数的区间[a, b],问你升职a人时几个人必被升职,b时几个人必升职,b时几个人没有可能被升职。

    思路:打比赛的时候一直想怎么做才能一个dfs直接打出一个节点的所有子节点数,发现总是弄不出来。结果这道题直接暴力搜索每个点的儿子就行了。

    我们正向建边求出所有下级(包括自己)son,反向建边求出所有上级(包括自己)fa,那么显然如果n - son < a时,也就是说剩下的人都升职都不够a人,那我肯定升职。如果fa > b时,显然我要升职至少要fa,但是b  < fa,那我就不可能升职。

    这题也太暴力了,这谁下得了手。

    代码:

    #include<set>
    #include<map>
    #include<stack>
    #include<cmath>
    #include<queue>
    #include<vector>
    #include<string>
    #include<cstdio>
    #include<cstring>
    #include<sstream>
    #include<iostream>
    #include<algorithm>
    typedef long longll;
    using namespace std;
    const int maxn = 5000 + 10;
    const int MOD = 1e9 + 7;
    const int INF = 0x3f3f3f3f;
    vector<int> G[maxn], g[maxn];
    int son[maxn], fa[maxn];
    bool vis[maxn];
    int dfs1(int u){
        vis[u] = true;
        int ret = 1;
        for(int i = 0; i < G[u].size(); i++){
            int v = G[u][i];
            if(!vis[v])
                ret += dfs1(v);
        }
        return ret;
    }
    int dfs2(int u){
        vis[u] = true;
        int ret = 1;
        for(int i = 0; i < g[u].size(); i++){
            int v = g[u][i];
            if(!vis[v])
                ret += dfs2(v);
        }
        return ret;
    }
    int main(){
        int a, b, n, m;
        scanf("%d%d%d%d", &a, &b, &n, &m);
        for(int i = 0; i < n; i++){
            G[i].clear();
            g[i].clear();
        }
        for(int i = 1; i <= m; i++){
            int u, v;
            scanf("%d%d", &u, &v);
            G[u].push_back(v);  //
            g[v].push_back(u);  //
        }
        int ans1 = 0, ans2 = 0, ans3 = 0;
        for(int i = 0; i < n; i++){
            memset(vis, false, sizeof(vis));
            son[i] = dfs1(i);
            memset(vis, false, sizeof(vis));
            fa[i] = dfs2(i);
            if(n - son[i] < a) ans1++;
            if(n - son[i] < b) ans2++;
            if(fa[i] > b) ans3++;
        }
        printf("%d
    %d
    %d
    ", ans1, ans2, ans3);
        return 0;
    }
  • 相关阅读:
    oracle拼接函数:将多个字段拼接在一行显示
    Source Insight 自定义命令说明
    harview .har文件解析
    GSM设备和网络错误代码
    mknod 创建设备
    linux下的usb抓包方法
    一些函数
    vmware 软件打开 自动开启虚拟机(快捷方式)
    Unix下C程序内存泄漏检测工具Valgrind安装与使用
    windows vmware 系统自启动
  • 原文地址:https://www.cnblogs.com/KirinSB/p/10841859.html
Copyright © 2011-2022 走看看