题目:P10480 可达性统计
题目描述
给定一张 N N N 个点 M M M 条边的有向无环图,分别统计从每个点出发能够到达的点的数量。
输入格式
第一行两个整数 N , M N,M N,M,接下来 M M M 行每行两个整数 x , y x,y x,y,表示从 x x x 到 y y y 的一条有向边。
输出格式
输出共 N N N 行,表示每个点能够到达的点的数量。
输入输出样例 #1
输入 #1
10 10
3 8
2 3
2 5
5 9
5 9
2 3
3 9
4 8
2 10
4 9
输出 #1
1
6
3
3
2
1
1
1
1
1
说明/提示
测试数据满足 1 ≤ N , M ≤ 30000 1 \le N,M \le 30000 1≤N,M≤30000, 1 ≤ x , y ≤ N 1 \le x,y \le N 1≤x,y≤N。
代码(60分)
#include<iostream>
#include<cstring>
using namespace std;
const int MaxN = 30000 + 10;
int N, M, h[MaxN], e[MaxN * 2], ne[MaxN * 2], idx, d[MaxN], q[MaxN], hh, tt = -1;
void init(){
memset(h, -1, sizeof h);
}
void add(int a, int b){
e[idx] = b;
ne[idx] = h[a];
h[a] = idx ++;
}
int bfs(int u){
memset(d, -1, sizeof d);
hh = 0, tt = -1;
q[++ tt] = u;
d[u] = 0;
int sum = 1;
while(hh <= tt){
int t = q[hh ++];
for(int i = h[t]; i != -1; i = ne[i]){
int j = e[i];
if(d[j] == -1){
q[++ tt] = j;
d[j] = d[t] + 1;
sum ++;
}
}
}
return sum;
}
int main(){
scanf("%d%d", &N, &M);
init();
while(M --){
int a, b;
scanf("%d%d", &a, &b);
add(a, b);
}
for(int i = 1; i <= N; i ++){
int res = bfs(i);
printf("%d\n", res);
}
return 0;
}