• 可达性统计


    题目链接

    题意:给定一张N个点M条边的有向无环图,分别统计从每个点出发能够到达的点的数量。N,M<=30000。

    思路:先拓扑排序,这样肯定拓扑序前面的肯定在拓扑序后面的点的前面。然后用状态压缩,用bitset转化成二进制,一顿从后往前按位或,有多少1就代表有多少个能达到的点的数量。

    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<bitset>
    #include<cmath>
    #include<queue>
    #include<iostream>
    using namespace std;
    const int maxn = 30000+7;
    int head[maxn],ver[maxn];
    int Next[maxn];
    int tot,cnt;
    int deg[maxn],a[maxn];
    int n,m;
    bitset<maxn> c[maxn];
    void add(int x, int y){
        ver[++tot] = y, Next[tot] = head[x];
        head[x] = tot;
        deg[y]++;
    }
     
    void toposort(){
        queue<int> q;
        for(int i = 1; i <= n; i++)
            if(deg[i] == 0) q.push(i);
        while(q.size()){
            int x = q.front();
            q.pop();
            a[++cnt] = x;
            for(int i = head[x]; i; i = Next[i]) {
                int y = ver[i];
                deg[y]--;
                if(deg[y] == 0) q.push(y);
            }
        }
    }
     
    void solve(){
        int x, y;
        for(int i = cnt; i >= 1; i--) {
            x = a[i];
            c[x][x] = 1;
            for(int j = head[x]; j; j = Next[j]) {
                int y = ver[j];
              
                c[x] |= c[y];
            }
        }
    }
     
    int main(){
        int x, y;
        scanf("%d %d", &n, &m);
        while(m--){
            scanf("%d %d", &x, &y);
            add(x, y);
        }
        toposort();
        solve();
        for(int i = 1; i <= n; i++)
            printf("%d
    ",c[i].count());
        return 0;
    }
  • 相关阅读:
    IO
    NIO
    Nginx(六)之负载均衡策略
    Nginx(五)之事件相关实现
    Nginx(四)之模块功能
    Nginx(三)之配置指令与内部运行逻辑
    Nginx(二)之数据结构
    Nginx(一)之整体架构框架
    HTTP(二)Web安全
    gson哪些符号html转义,Gson-特殊字符的转义-disableHtmlEscaping()
  • 原文地址:https://www.cnblogs.com/2462478392Lee/p/11285039.html
Copyright © 2020-2023  润新知