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;
}
相关推荐
a1879272183141 分钟前
【算法】动态规划第四篇:背包收官——min 哨兵、计数世界与组合排列分水岭
算法·leetcode·动态规划·dp·01背包·算法讲解·决策合并
2601_962297481 小时前
在python3中、下列输出变量a的正确写法是_2020超星大数据Python免费答案
数据结构·python·算法·编程·字符串操作
辰烨chenye1 小时前
LeetCode Hot 100 题解 · 子串篇
算法·leetcode·职场和发展
辰烨chenye1 小时前
LeetCode Hot 100 题解 · 堆篇
java·算法·leetcode
手写码匠2 小时前
华为云Flexus+DeepSeek征文|DeepSeek 应用监控告警体系实战:从“用户投诉才知道“到“故障前就发现“
人工智能·深度学习·算法·aigc
shehuiyuelaiyuehao2 小时前
算法29,前缀和,除自身以外的数组的乘积
java·数据结构·算法
智购科技自动售货机厂家2 小时前
2026自动售货机设备清洁效果自动验证:从图像比对到评分算法的工程实践~YH
人工智能·算法·计算机视觉
姜穆澜3 小时前
机器学习实战指南:从算法原理到工程落地
人工智能·算法·机器学习
啵啵啵鱼3 小时前
DS-顺序表
java·数据结构·笔记·后端·链表·obsidian