P10480 可达性统计

P10480 可达性统计

题目描述

给定一张 NNN 个点 MMM 条边的有向无环图,分别统计从每个点出发能够到达的点的数量。

输入格式

第一行两个整数 N,MN,MN,M,接下来 MMM 行每行两个整数 x,yx,yx,y,表示从 xxx 到 yyy 的一条有向边。

输出格式

输出共 NNN 行,表示每个点能够到达的点的数量。

输入输出样例 #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≤300001 \le N,M \le 300001≤N,M≤30000,1≤x,y≤N1 \le x,y \le N1≤x,y≤N。

对于这题,可以采用逆向拓扑排序,从出度为0的结点开始向前更新。利用bitset来进行集合的合并。若仅仅简单相加,会导致重复统计。

cpp 复制代码
#include<bits/stdc++.h>
using namespace std;

int main(){
    int n, m;
    cin>>n>>m;
    vector<bitset<30001>> dp(n+1);
    vector<vector<int>> g(n+1);
    vector<int> in_(n+1, 0);
    vector<int> out_(n+1, 0);
    priority_queue<int, vector<int>, greater<>> pq;
    for(int i = 1;i<=m;i++){
        int u, v;
        cin>>u>>v;
        g[v].push_back(u);
        in_[v]++;
        out_[u]++;
    }
    for(int i = 1;i<=n;i++){
        if(!out_[i]){
            pq.emplace(i);
        }
        dp[i][i] = 1;
    }
    while(!pq.empty()){
        int v = pq.top();
        pq.pop();
        for(auto i : g[v]){
            out_[i]--;
            dp[i] |= dp[v];
            if(!out_[i]){
                pq.emplace(i);
            }
        }
    }
    for(int i = 1;i<=n;i++){
        cout<<dp[i].count()<<'\n';
    }
    return 0;
}
相关推荐
VT.馒头几秒前
【力扣】2694. 事件发射器
前端·javascript·算法·leetcode·职场和发展·typescript
星火开发设计3 分钟前
命名空间 namespace:解决命名冲突的利器
c语言·开发语言·c++·学习·算法·知识
知无不研8 分钟前
选择排序算法
数据结构·算法·排序算法·选择排序
好学且牛逼的马9 分钟前
【Hot100|21-LeetCode 160. 相交链表】
算法·leetcode
爱学习的阿磊9 分钟前
C++中的策略模式应用
开发语言·c++·算法
郝学胜-神的一滴10 分钟前
Python中的bisect模块:优雅处理有序序列的艺术
开发语言·数据结构·python·程序人生·算法
筵陌12 分钟前
算法:位运算
算法
Christo317 分钟前
TKDE-2026《Efficient Co-Clustering via Bipartite Graph Factorization》
人工智能·算法·机器学习·数据挖掘
2401_8384725118 分钟前
C++异常处理最佳实践
开发语言·c++·算法
m0_7369191022 分钟前
C++中的类型标签分发
开发语言·c++·算法