1191 家谱树(拓扑排序)

1191 家谱树(拓扑排序)1 问题描述 有个人的家族很大 辈分关系很混乱 请你帮整理一下这种关系 给出每个人的孩子的信息 输出一个序列 使得每个人的孩子都比那个人后列出 输入格式第 1 行一个整数 n 表示家族的人数 接下来 n 行 第 i 行描述第 i 个人的孩子 每行最后是 0 表示描述完毕 每个人的编号从 1 到 n 输出格式输出一个序列 使得每个人的孩子都比那个人后列出 数据保证一定有解 如果有多解输出任意一解 数据范围 1 n 100 输入样例

1. 问题描述:

有个人的家族很大,辈分关系很混乱,请你帮整理一下这种关系。给出每个人的孩子的信息。输出一个序列,使得每个人的孩子都比那个人后列出。

输入格式

第 1 行一个整数 n,表示家族的人数;接下来 n 行,第 i 行描述第 i 个人的孩子;每行最后是 0 表示描述完毕。每个人的编号从 1 到 n。

输出格式

输出一个序列,使得每个人的孩子都比那个人后列出;数据保证一定有解,如果有多解输出任意一解。

数据范围

1 ≤ n ≤ 100

输入样例:

输出样例:

2. 思路分析:

分析题目可以知道我们可以将每一个人看成是一个节点,本质上求解的是拓扑排序的序列,拓扑排序是对于有向图来说的,使得每一条边都是前面的节点指向后面的节点,当存在环的时候是没有拓扑排序的,如果一个有向图可以拓扑排序那么这个图称为拓扑图,拓扑图等价于有向无环图。算法流程:

  • 遍历每一条边的时候统计节点的入度;
  • 将所有入度为0的点入队,当队列非空的时候执行循环,弹出队头元素,遍历队头元素的所有出边,将出边对应的节点的入度减1,如果发现度数为0之后那么将其加入到队列中,并且所有度数为0的节点都是拓扑排序的序列。

3. 代码如下:

import collections from typing import List class Solution: def topsort(self, n: int, d: List[int], g: List[List[int]], res: List[int]): q = collections.deque() for i in range(1, n + 1): # 将入度为0的点入队 if d[i] == 0: q.append(i) res.append(i) while q: # 弹出队首节点 p = q.popleft() # 遍历p的所有邻接点 for next in g[p]: # 对应的入度减1 d[next] -= 1 # 入度为0之后将当前节点加入到队列中 if d[next] == 0: q.append(next) # 拓扑排序的序列中加入当前的节点next res.append(next) def process(self): n = int(input()) # 邻接表 g = [list() for i in range(n + 10)] d = [0] * (n + 10) for i in range(1, n + 1): s = input() # 当len(s) == 1的时候说明没有孩子 if len(s) > 1: s = s.split() for j in range(len(s) - 1): t = int(s[j]) g[i].append(t) d[t] += 1 res = list() # 拓扑排序 self.topsort(n, d, g, res) for x in res: print(x, end=" ") if __name__ == "__main__": Solution().process()
from typing import List import collections class Solution: def process(self): n = int(input()) g = [list() for i in range(n + 10)] # d用来统计入度 d = [0] * (n + 10) for i in range(1, n + 1): s = input().split() if len(s) > 1: for j in range(len(s) - 1): t = int(s[j]) g[i].append(t) d[t] += 1 res = list() self.topsort(n, d, g, res) for x in res: print(x, end=" ") def topsort(self, n: int, d: List[int], g: List[List[int]], res: List[int]): q = collections.deque() for i in range(1, n + 1): if d[i] == 0: q.append(i) while q: p = q.popleft() # 每一个弹出来的节点都是入度为0的点为拓扑排序的序列 res.append(p) for next in g[p]: d[next] -= 1 if d[next] == 0: q.append(next) if __name__ == "__main__": Solution().process()
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/232829.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • Redisson分布式锁的简单使用

    redis分布式锁学习和集成框架Redisson分布式锁的一些简单使用

    2022年3月1日
    52
  • Kafka如何删除topic中的部分数据_kafka修改topic副本数

    Kafka如何删除topic中的部分数据_kafka修改topic副本数概述  在平时对kafka…

    2022年10月16日
    3
  • linux抓包怎么查看数据包_shell curl获取返回数据

    linux抓包怎么查看数据包_shell curl获取返回数据(1)想要截获所有210.27.48.1的主机收到的和发出的所有的分组:#tcpdumphost210.27.48.1(2)想要截获主机210.27.48.1和主机210.27.48.2或210.27.48.3的通信,使用命令(注意:括号前的反斜杠是必须的):#tcpdumphost210.27.48.1and(210.27.48.2or210.27.48.3)(3)如…

    2022年10月14日
    3
  • 《天下强汉》6、西汉历史的最后一抹辉煌——绝域名将陈汤

    《天下强汉》6、西汉历史的最后一抹辉煌——绝域名将陈汤【档案】  姓名:陈汤,字子公  生卒:约公元前75年—约公元前5年  性别:男  外貌:双臂半残  籍贯:山阳瑕丘人(今山东兖州东北)  家庭出身:穷书生,业余乞丐  学历:自学成才  著作:《汉射声校尉陈汤集》二卷,已失传  经典战役:远袭中亚郅支之战  战功:亲诛郅支单于,威行外国  特技:火攻,鼓舞,强行  特长:学识渊博,精于著文,具备非凡的决断力和行动力  爱好:读书,登山,钱财,交友…

    2022年5月31日
    78
  • visual studio 2015序列号_怎么激活win7旗舰版

    visual studio 2015序列号_怎么激活win7旗舰版我安装的是VisualStudioTeamSystem2008版本,适用版本90天。用了两个月后,每次打开出现提示:还有30天过期了,29天过期了,28天过期了。。。每次看到这个提示心中总有不爽。于是上网找序列号, 在网上找了好久,好像就一个序列号:PYHYP-WXB3B-B2CCM-V9DX9-VDY8T。 下面是win7的操作1,控制面板\程序\程序和

    2022年8月10日
    13
  • 十大经典排序算法(C语言实现)[通俗易懂]

    十大经典排序算法(C语言实现)[通俗易懂]原文链接:https://www.cnblogs.com/onepixel/articles/7674659.html1、冒泡排序(BubbleSort)冒泡排序是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果它们的顺序错误就把它们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经…

    2022年5月9日
    54

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号