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;
}
相关推荐
迷途之人不知返6 小时前
算法系列2:滑动窗口
算法
Herbert_hwt6 小时前
C语言零基础入门:循环控制与数据类型详解
c语言·数据结构·算法
晚风醉蝶7 小时前
1-6-插入排序-InsertionSort
java·数据结构·排序算法
Tyler_TXZ8 小时前
C++C语言之——二叉树
c语言·开发语言·数据结构·c++·二叉树
Tisfy8 小时前
LeetCode 3090.每个字符最多出现两次的最长子字符串:二重循环 / 滑动窗口
算法·leetcode·字符串·题解·模拟·双指针·滑动窗口
-dzk-8 小时前
【技巧】LC 136.只出现一次的数字
算法·异或
有点。8 小时前
C++二叉树二(练习题)
数据结构·c++·算法·图论
专注仿真9 小时前
问答大模型技术方案算法实现-RAPTOR树构建算法与BEG集成使用
python·算法
zlinear数据采集卡9 小时前
数据采集卡从入门到精通(10):采样率与分辨率的核心关系——反比律、架构分布与过采样
arm开发·嵌入式硬件·算法·fpga开发·架构·开源
白狐_79810 小时前
408 数据结构|线索二叉树两题详解:先序线索化后的空链域 + 中序前驱/后继判断
c语言·数据结构·链表