给定一张N个点M条边的有向无环图,分别统计从每个点出发能够到达的点的数量。
输入格式
第一行两个整数N,M,接下来M行每行两个整数x,y,表示从x到y的一条有向边。
输出格式
输出共N行,表示每个点能够到达的点的数量。
数据范围
1≤N,M≤30000
思路:先排好序,我们知道排完序越靠后的数是由前面的数转移过来的,这里用到bitset,可以计算1的个数。
注意++tot
#include<iostream>
#include<cstdio>
#include<bitset>
#include<queue>
#include<cstring>
using namespace std;
const int N=3e4+10;
int n,m,tot;
struct node{
int to,ne;
}edge[30005];
int fir[30005],p[N],in[N],k;
bitset<N> f[N];
void add(int u,int v){
edge[++tot].to=v;
edge[tot].ne=fir[u];
fir[u]=tot;
}
void tp(){
queue<int> q;
for(int i=1;i<=n;i++){
if(in[i]==0)q.push(i);
}
k=0;
while(q.size()){
int t=q.front();
p[++k]=t;
q.pop();
for(int i=fir[t];i;i=edge[i].ne){
in[edge[i].to]--;
if(in[edge[i].to]==0){
q.push(edge[i].to);
}
}
}
}
int main(){
scanf("%d%d",&n,&m);
int x,y;
memset(fir,0,sizeof(fir));
memset(in,0,sizeof(in));
tot=0;
while(m--){
scanf("%d%d",&x,&y);
in[y]++;
add(x,y);
}
tp();
// cout<<k<<"pp"<<endl;
for(int i=k;i>=1;i--){
x=p[i];
f[x][x]=1;
for(int j=fir[x];j;j=edge[j].ne){
int v=edge[j].to;
f[x]|=f[v];
}
}
for(int i=1;i<=n;i++){
cout<<f[i].count()<<endl;
}
return 0;
}