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;
}
相关推荐
JuneXcy1 小时前
循环高级(1)
c语言·开发语言·算法
流火无心2 小时前
mysql索引 底层数据结构与算法
数据结构·mysql·索引
Ka1Yan3 小时前
什么是策略模式?策略模式能带来什么?——策略模式深度解析:从概念本质到Java实战的全维度指南
java·开发语言·数据结构·算法·面试·bash·策略模式
绝无仅有3 小时前
Go Timer 面试指南:常见问题及答案解析
后端·算法·架构
地平线开发者4 小时前
开发者说|H-RDT:基于人类操作数据的跨本体机器人学习
算法·自动驾驶
biuyyyxxx6 小时前
Excel数组学习笔记
笔记·学习·算法
南莺莺6 小时前
//Q是一个队列,S是一个空栈,实现将队列中的元素逆置的算法。
数据结构·算法·链表·
闻缺陷则喜何志丹6 小时前
【分治法 BFS 质因数分解】P12255 [蓝桥杯 2024 国 Java B] 园丁|普及+
c++·算法·蓝桥杯·宽度优先·质因数分解·分治法
寒冬没有雪6 小时前
按对角线进行矩阵排序
c++·算法
Huangichin6 小时前
C++基础算法——贪心算法
c++·算法·贪心算法