2101 可达性统计

Posted willendless

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2101 可达性统计相关的知识,希望对你有一定的参考价值。

【题目描述】
    给定一张N个点M条边的有向无环图,分别统计从每个点出发能够到达的点的数量。N,M≤30000。
【题目链接】

2101 可达性统计

【算法】

拓扑排序之后逆序计算,bitset状态压缩模拟集合的并操作。

【代码】
#include <bits/stdc++.h>
using namespace std;
int n,m,tot,cnt;
struct edge{ int to,next; }e[30010];
int head[30010],topn[30010],deg[30010];
bitset <30010> s[30010];
inline int read() {
    int x=0,f=1; char c=getchar();
    while(c<‘0‘||c>‘9‘) { if(c==‘-‘) f=-1; c=getchar(); }
    while(c>=‘0‘&&c<=‘9‘) { x=x*10+c-‘0‘; c=getchar(); }
    return x*f;
}
void add(int x,int y) {
    e[++tot].to=y,e[tot].next=head[x];
    head[x]=tot,deg[y]++;
}
void topsort() {
    queue<int> q;
    for(int i=1;i<=n;i++) if(!deg[i]) q.push(i);
    while(q.size()) {
        int x=q.front(); q.pop();
        topn[++cnt]=x;
        for(int i=head[x];i;i=e[i].next) {
            int to=e[i].to; deg[to]--;
            if(!deg[to]) q.push(to);
        }
    }
}
int main() {
    n=read(),m=read();
    for(int i=1;i<=m;i++) {
        int a,b;
        a=read(),b=read();
        add(a,b);
    }
    topsort();
    for(int i=cnt;i>=1;i--) {
        int x=topn[i];
        s[x][x]=1;
        for(int j=head[x];j;j=e[j].next) {
            int to=e[j].to;
            s[x]|=s[to];
        }
    }
    for(int i=1;i<=n;i++) printf("%d
",s[i].count());
    return 0;
}

以上是关于2101 可达性统计的主要内容,如果未能解决你的问题,请参考以下文章

CH2101 可达性统计 解题报告

CH2101可达性统计

CH 2101 - 可达性统计 - [BFS拓扑排序+bitset状压]

可达性统计

「拓扑排序」可达性统计

可达性统计