蓝桥杯第793题——排水系统

题目描述

对于一个城市来说,排水系统是极其重要的一个部分。

有一天,小 C 拿到了某座城市排水系统的设计图。排水系统由 n 个排水结点(它们从 1∼n 编号)和若干个单向排水管道构成。每一个排水结点有若干个管道用于汇集其他排水结点的污水(简称为该结点的汇集管道),也有若干个管道向其他的排水结点排出污水(简称为该结点的排出管道)。

排水系统的结点中有 m 个污水接收口,它们的编号分别为 1,2,…,m,污水只能从这些接收口流入排水系统,并且这些结点没有汇集管道。排水系统中还有若干个最终排水口,它们将污水运送到污水处理厂,没有排出管道的结点便可视为一个最终排水口。

现在各个污水接收口分别都接收了 1 吨污水,污水进入每个结点后,会均等地从当前结点的每一个排出管道流向其他排水结点,而最终排水口将把污水排出系统。

现在小 C 想知道,在该城市的排水系统中,每个最终排水口会排出多少污水。该城市的排水系统设计科学,管道不会形成回路,即不会发生污水形成环流的情况。

输入描述

第一行两个用单个空格分隔的整数 n,m。分别表示排水结点数与接收口数量。

接下来 n 行,第 i 行用于描述结点 i 的所有排出管道。其中每行第一个整数 di​ 表示其排出管道的数量,接下来 di​个用单个空格分隔的整数 a1​,a2​,…,adi​​ 依次表示管道的目标排水结点。 保证不会出现两条起始结点与目标结点均相同的管道。

其中,1 ≤ n ≤ 10^5,1 ≤ m ≤ 10,0 ≤ di ​≤ 5。

数据保证,污水在从一个接收口流向一个最终排水口的过程中,不会经过超过 1010 个中间排水结点(即接收口和最终排水口不算在内)。

输出描述

输出若干行,按照编号从小到大的顺序,给出每个最终排水口排出的污水体积。其中体积使用分数形式进行输出,即每行输出两个用单个空格分隔的整数 p,q,表示排出的污水体积为 \frac{p}{q}​ 。要求 p 与 q 互素,q=1 时也需要输出 q。

输入输出样例

示例 1

输入

5 1
3 2 3 5
2 4 5
2 5 4
0
0

输出

1 3
2 3

 解题思路

本题是有向无环图的拓扑排序,而拓扑排序其实就是在图上的搜索,本质上就是dfs和bfs。

这题是典型的有起点有终点的有向图,我们自然而然的想到使用bfs进行遍历,一般像这样的题我们有以下需要关注的点:

  1. 使用邻接表存储点很多的稀疏图;使用ru和chu两个长度为n的数组记录每个点的入度和出度;使用链式队列完成bfs等。
  2. 通常我们可以开辟dp数组记录节点状态,但是本题比较特殊,对于每个点的状态使用p和q组合的一个分数来表示,这样我们就可以利用p和q数组代替dp数组记录节点状态了。

这道题需要我们对分数除法、分数加法、分数约分的过程进行模拟,其内容笔者使用了一个addWater方法进行操作,调用了最大公约数gcd和最小公倍数lcm算法,属于算法有关基础数学知识的内容。

这里需要注意的是,由于分数可能很大,所以我们不仅需要使用long类型进行存储计算,还要对求最小公倍数的时候先除以最大公因数再乘第二个数,否则有可能溢出。

代码题解

具体的代码并没有难以理解的地方,以下是具体的代码:

import java.io.*;
import java.util.*;public class Main {static int n, m;static ArrayList<ArrayList<Integer>> edges;static int[] ru, chu;static long[] p, q;static Queue<Integer> qu;public static void main(String[] args) throws IOException {BufferedReader in = new BufferedReader(new InputStreamReader(System.in));PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));String[] temp = in.readLine().split(" ");n = Integer.parseInt(temp[0]);m = Integer.parseInt(temp[1]);init();for (int i = 1; i <= n; i++) {temp = in.readLine().split(" ");int t = Integer.parseInt(temp[0]);chu[i] = t;for (int j = 1; j <= t; j++) {int next = Integer.parseInt(temp[j]);edges.get(i).add(next);ru[next]++;}}for (int i = 1; i <= m; i++) {qu.add(i);p[i] = 1;q[i] = 1;}while (!qu.isEmpty()) {int t = qu.poll();for (int e : edges.get(t)) {addWater(t, e, chu[t]);ru[e]--;if (ru[e] == 0 && chu[e] > 0) {qu.add(e);}}p[t] = 0;q[t] = 0;}for (int i = 1; i <= n; i++) {if (p[i] != 0) {out.print(p[i]);out.print(" ");out.print(q[i]);out.print("\n");}}out.flush();}public static void addWater(int sourse, int target, int num) {long p1 = p[sourse];long q1 = q[sourse];long t = gcd(p1, num);p1 /= t;q1 *= num / t;long p2 = p[target];long q2 = q[target];if (p2 == 0) {p[target] = p1;q[target] = q1;} else {long x = lcm(q1,  q2);long t1 = x / q1 * p1 + x / q2 * p2;long t2 = x;long tt = gcd(t1, t2);p[target] = t1 / tt;q[target] = t2 / tt;}}public static long gcd(long a, long b) {return a % b == 0 ? b : gcd(b, a % b);}public static long lcm(long a, long b) {return a / gcd(a, b) * b;}public static void init() {edges = new ArrayList<>();for (int i = 0; i <= n; i++) {edges.add(new ArrayList<>());}p = new long[n + 1];q = new long[n + 1];ru = new int[n + 1];chu = new int[n + 1];qu = new LinkedList<>();}
}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

LeetCode.1379. 找出克隆二叉树中的相同节点

题目 1379. 找出克隆二叉树中的相同节点 分析 这道题目其实利用的是递归的思想&#xff0c;同时遍历两棵树即可。具体流程&#xff08;下面所讲解的流程基于的前提一定是两棵树一起遍历哦&#xff09;&#xff1a; 如果 original 为空节点&#xff0c;直接返回 null&#…

无极低码:免费版部署操作指南

无极低码 :https://wheart.cn 无极低码:免费试用版部署过程参照: 无极低码部署版操作指南 https://wheart.cn/so/home?m=index&id=ad614930-d936-11ee-8489-525400be6368 ” 。 下载完解压成后进行部署

OpenHarmony Neptune开发板-MQTT连接华为IoT平台

本示例将演示如何在Neptune开发板上使用MQTT协议连接华为IoT平台,使用的是ATH20温湿度传感器模块与Neptune开发板 本示例实现AHT20温湿度数据上报华为IoT平台,IoT平台下发命令控制LED灯的开关 使用W800 SDK功能包中libemqtt来实现连接华为IoT平台 程序设计 初始化 一、MQT…

Express框架搭建项目 node.js

文章目录 引言Express框架介绍express安装环境准备写一个简单的项目展示 文章总结 引言 Express是一个基于Node.js平台的轻量级Web应用框架&#xff0c;它提供了简洁的API和丰富的功能&#xff0c;使得开发者能够快速地构建Web服务器和API。本文将带领大家从零开始&#xff0c…

自动驾驶之心规划控制笔记

Search-based Path Planning Methods Path Finding Problem 一般来说指标有距离,耗费时间,能量,或者多目标。 左图是拓扑地图,蓝色的点就是顶点,绿色的线是连接关系。最后得到的是一个从哪里走的一个最优,并非精细解。 右图是栅格地图,这个搜索出来的是在相对分辨率比…

【c语言】自定义类型:联合体(公用体)【详解】

联合体 联合体类型的声明 像结构体⼀样&#xff0c;联合体也是由⼀个或者多个成员构成&#xff0c;这些成员可以不同的类型。但是编译器只为最⼤的成员分配⾜够的内存空间。联合体的特点是所有成员共⽤同⼀块内存空间。所以联合体也叫&#xff1a;共用体。 给联合体其中⼀个成…

《极客时间TonyBai go语言第一课》学习笔记

文章目录 前置篇显式组合并发 入门篇Go 包的初始化次序![在这里插入图片描述](https://img-blog.csdnimg.cn/direct/1388d0d1bddd4a37b98eba5fcb41fc4d.png)初始化一个项目 大纲 前置篇 显式 在 C 语言中&#xff0c;下面这段代码可以正常编译并输出正确结果&#xff1a; #i…

ubuntu安装sublime3并设置中文

安装Sublime Text 3 在Ubuntu上安装Sublime Text 3可以通过以下步骤进行&#xff1a; 打开终端。 导入Sublime Text 3的GPG密钥&#xff1a; wget -qO- https://download.sublimetext.com/sublimehq-pub.gpg | sudo apt-key add - 添加Sublime Text 3的存储库&#xff1a; …

v-text 和v-html

接下来&#xff0c;我讲介绍一下v-text和v-html的使用方式以及它们之间的区别。 使用方法 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-widt…

ssm023实验室耗材管理系统设计与实现+jsp

实验室耗材管理系统的设计与实现 摘 要 互联网发展至今&#xff0c;无论是其理论还是技术都已经成熟&#xff0c;而且它广泛参与在社会中的方方面面。它让信息都可以通过网络传播&#xff0c;搭配信息管理工具可以很好地为人们提供服务。针对实验室耗材信息管理混乱&#xff…

对一个类中具有相似名称的属性值进行操作

一、问题描述 对于一个类&#xff0c;要依次取得相似的属性名称进行相关操作&#xff0c;如果逐个get(),set()会非常麻烦&#xff0c;例如将属性值逐个求和后放入list。写代码时&#xff0c;首先需要声明一个Integer变量&#xff0c;然后使用去赋值&#xff0c;非常麻烦。类似…

《深入Linux内核架构》第3章 内存管理(6)

目录 3.5.7 内核中不连续页的分配 3.5.8 内核映射 本节讲解vmalloc, vmap&#xff0c;kmap原理。 3.5.7 内核中不连续页的分配 kmalloc函数&#xff1a;分配物理地址和虚拟地址都连续的内存。 kmalloc基于slab&#xff0c;而slab基于伙伴系统。 void *vmalloc(unsigned lon…