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;
}
相关推荐
前端炒粉1 小时前
18.矩阵置零(原地算法)
javascript·线性代数·算法·矩阵
im_AMBER1 小时前
数据结构 09 二叉树作业
数据结构·笔记·学习
暴风鱼划水2 小时前
三维重建【0-D】3D Gaussian Splatting:相机标定原理与步骤
算法·3d
l1t3 小时前
利用DeepSeek修改数据结构提升求解集合程序效率
数据结构·python·deepseek
mount_myj4 小时前
敏感信息屏蔽(一)【java】
java·算法·极课堂
先做个垃圾出来………5 小时前
偏移量解释
数据结构·算法
FanXing_zl5 小时前
基于整数MCU的FOC控制定标策略深度解析
单片机·嵌入式硬件·mcu·算法·定点运算·q15
立志成为大牛的小牛5 小时前
数据结构——三十三、Dijkstra算法(王道408)
数据结构·笔记·学习·考研·算法·图论
地平线开发者6 小时前
mul 与 reduce_sum 的优化实例
算法·自动驾驶