題目: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;
}