可达性统计

Posted hhyx

tags:

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

# 题意
给定n个点m条边的有向无环图,统计从每个点出发所能到达的点的数量

# 题解
统计的是从x出发的后继能够到达的点的并集和其自身。
用一个二进制数表示当前节点可以到的节点,第 i 位为1就是可以到达
f(i)就表示 i 可达的点,计算出来一个拓扑序列,
按照拓扑序列的倒序算过来即可,开始的时候所有点只能到达自己,从拓扑序列的从后一个点开始算递推即可,最后一个数没有出边。
bitset开数组

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 const int N=3e4+10;
 4 int e[N],h[N],ne[N],idx;
 5 int d[N];
 6 bitset<N>f[N];
 7 int tsort[N],cnt;
 8 int n,m;
 9 void add(int x,int y){
10    e[idx]=y,ne[idx]=h[x],h[x]=idx++;
11    d[y]++;
12 }
13 void topsort(){
14    queue<int>q;
15    for(int i=1;i<=n;i++)
16       if(d[i]==0)
17          q.push(i);
18    while(q.size()){
19       int x=q.front();
20       q.pop();
21       tsort[++cnt]=x;
22       for(int i=h[x];i!=-1;i=ne[i]){
23          int y=e[i];
24          if(--d[y]==0) q.push(y);
25       }
26    }
27 }
28 void cal(){
29    for(int i=cnt;i;i--){
30       int x=tsort[i];
31       f[x][x]=1;//即初始化,bitset 中第i个点的数字的第i位为1,即可以到达自身
32       for(int i=h[x];i!=-1;i=ne[i]){
33          int y=e[i];
34          f[x] |= f[y];
35       }
36    }
37 }
38 int main(){
39    cin>>n>>m;
40    memset(h,-1,sizeof h);
41    while(m--){
42       int x,y;
43       cin>>x>>y;
44       add(x,y);
45    }
46    topsort();
47    cal();
48    for(int i=1;i<=n;i++)
49       cout<<f[i].count()<<endl;
50 }

 

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

「拓扑排序」可达性统计

可达性统计

2101 可达性统计

CH2101 可达性统计 解题报告

CH2101可达性统计

可达性统计(拓扑排序)