《算法竞赛进阶指南》0x21有向无环图中点的可达性统计 topsort+bitset

Posted randy-lo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《算法竞赛进阶指南》0x21有向无环图中点的可达性统计 topsort+bitset相关的知识,希望对你有一定的参考价值。

题目链接:https://www.acwing.com/problem/content/description/166/

计算有向无环图中每个点可达的点的数量,可以先通过拓扑排序确定点的拓扑序,因为在一个点处理之前,他所能到达的所有点都要先被处理,所以我们处理的顺序

只要是按照拓扑排序的逆序处理就能在这个点被处理之前就把该点所能到达的所有点都先处理完.这道题的空间复杂度经过计算可以发现约是1e7,128M空间

代码:

#include<iostream>
#include<bitset>
#include<queue>
#include<string.h>
#define maxn 30010
using namespace std;
int head[maxn],nxt[maxn],ver[maxn];
bitset<30010> f[30010];
int a[maxn];//存放top序
int deg[maxn];
int tot=0;
int n,m;
int cnt=0;
void addedge(int u,int v){
    ver[++tot]=v;
    nxt[tot]=head[u];
    head[u]=tot;
} 
void topsort(){
    queue<int> q;
    for(int i=1;i<=n;i++)if(!deg[i])q.push(i);
    while(!q.empty()){
        int x=q.front();
        q.pop();
        a[++cnt]=x;
        for(int i=head[x];i;i=nxt[i]){
            int y=ver[i];
            if(!(--deg[y]))q.push(y);
        }
    }
}
void calc(){
    for(int i=cnt;i>=1;i--){
        int x=a[i];//按照topsort的逆序进行处理 
        f[x][x]=1;//设置顶点x能到达它自己 
        for(int i=head[x];i;i=nxt[i]){
            int y=ver[i];
            f[x]|=f[y];
        } 
    }
}
int main(){
    cin>>n>>m;
    for(int i=0;i<m;i++){
        int u,v;
        scanf("%d%d",&u,&v);
        addedge(u,v);
        deg[v]++;
    }
    topsort();
    calc();
    for(int i=1;i<=n;i++)printf("%d
",f[i].count());
} 

 

以上是关于《算法竞赛进阶指南》0x21有向无环图中点的可达性统计 topsort+bitset的主要内容,如果未能解决你的问题,请参考以下文章

在有向无环图中找到最低共同祖先的算法?

有向无环图的判定及拓扑排序

使用 BFS/DFS 寻找有向无环图中权重最大的路径

正加权有向无环图中的k-边最短路径

AcWing:164. 可达性统计(拓扑排序 + 状态压缩算法)

在有向无环图中求最长路径