标签:front name pop memset eof 一个 include 就是 --
# 题意
给定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 }
标签:front name pop memset eof 一个 include 就是 --
原文地址:https://www.cnblogs.com/hhyx/p/12432252.html