求助,关于拓扑排序,一个站外的模板题
  • 板块学术版
  • 楼主XSean
  • 当前回复1
  • 已保存回复1
  • 发布时间2023/2/21 16:21
  • 上次更新2023/10/24 00:11:27
查看原帖
求助,关于拓扑排序,一个站外的模板题
546830
XSean楼主2023/2/21 16:21

给定一张 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;   
}
2023/2/21 16:21
加载中...