给定一张 N 个点 M 条边的有向无环图,分别统计从每个点出发能够到达的点的数量。
输入格式 第一行两个整数 N,M ,接下来 M 行每行两个整数 x,y ,表示从 x 到 y 的一条有向边。
输出格式 输出共 N 行,表示每个点能够到达的点的数量。
数据范围 1≤N,M≤30000 , 1≤x,y≤N 输入样例: 10 10
3 8
2 3
2 5
5 9
5 9
2 3
3 9
4 8
2 10
4 9
输出样例: 1
6
3
3
2
1
1
1
1
1
这个是正确的代码
#include <bits/stdc++.h>
#define prf printf
#define sf scanf
template <typename T> inline void rd(T &x){
x = 0; bool f = true; char ch = getchar();
while(ch < '0' || ch > '9'){ f = ch == '-' ? false : true; ch = getchar();}
while(ch >= '0' && ch <= '9'){ x = (x << 1) + (x << 3) + (ch ^ '0'); ch = getchar();}
if(!f) x = -x;
}
template <typename T, typename ...Args> inline void rd(T &x, Args &...args){ rd(x); rd(args...);}
using namespace std;
const int N = 30010;
int n, m;
int h[N], e[N], ne[N], idx;
bitset<N> s[N], ans[N];
int ind[N];
int order[N], ocnt;
void add(int a, int b){
e[++idx] = b, ne[idx] = h[a], h[a] = idx;
ind[b]++;
}
void topsort(){
queue<int> q;
for(int i = 1; i <= n; i++) if(!ind[i]) q.push(i);
while(q.size()){
int t = q.front(); q.pop();
for(int i = h[t]; i; i = ne[i]){
int j = e[i];
if(!--ind[j]) q.push(j);
}
order[++ocnt] = t;
}
}
void work(){
for(int i = n; i >= 1; i--){
int t = order[i];
ans[t][t] = 1;
for(int j = h[t]; j; j = ne[j]){
int k = e[j];
ans[t] |= ans[k];
}
}
}
int main(){
rd(n, m);
for(int i = 1; i <= m; i++){
int a, b; rd(a, b);
add(a, b);
}
topsort();
work();
for(int i = 1; i <= n; i++) prf("%d\n", ans[i].count());
return 0;
}
这个是错误的代码
#include <bits/stdc++.h>
#define prf printf
#define sf scanf
template <typename T> inline void rd(T &x){
x = 0; bool f = true; char ch = getchar();
while(ch < '0' || ch > '9'){ f = ch == '-' ? false : true; ch = getchar();}
while(ch >= '0' && ch <= '9'){ x = (x << 1) + (x << 3) + (ch ^ '0'); ch = getchar();}
if(!f) x = -x;
}
template <typename T, typename ...Args> inline void rd(T &x, Args &...args){ rd(x); rd(args...);}
using namespace std;
const int N = 30010;
int n, m;
int h[N], e[N], ne[N], idx;
bitset<N> s[N];
int ind[N];
int order[N], ocnt;
int ans[N];
void init(){
for(int i = 1; i <= n; i++) s[i][i] = 1;
}
void add(int a, int b){
e[++idx] = b, ne[idx] = h[a], h[a] = idx;
ind[b]++, s[a][b] = 1;//
}
void topsort(){
queue<int> q;
for(int i = 1; i <= n; i++) if(!ind[i]) q.push(i);
while(q.size()){
int t = q.front(); q.pop();
for(int i = h[t]; i; i = ne[i]){
int j = e[i];
if(!--ind[j]) q.push(j);
}
order[++ocnt] = t;
}
}
int calc(int x){
bitset<N> res; res.reset();
res[x] = 1;
for(int i = h[x]; i; i = ne[i]){
int j = e[i];
res |= s[j];
}
return res.count();
}
void work(){
for(int i = n; i >= 1; i--){
ans[order[i]] = calc(order[i]);
}
}
int main(){
rd(n, m);
init();
for(int i = 1; i <= m; i++){
int a, b; rd(a, b);
add(a, b);
}
topsort();
work();
for(int i = 1; i <= n; i++) prf("%d\n", ans[i]);
return 0;
}