数据结构与算法python版 MOOC 第十二周

十二、图及算法-下

本系列博客基于“ (北京大学)数据结构与算法python版”慕课,课程在中国大学慕课bilibili上均可找到。

1. 内容

  1. 深度优先搜索DFS算法
  2. 图的应用:拓扑排序,强连通分支,最短路径,最小生成树,

2. 课程代码

GitHub中下载

3. OJ作业

所有代码均可在github中下载

3.1 先修课

题目内容:
   有 n 门课程要选,其编号分别由 0 至 n-1。每个课程都有一些需要提前学完的先修课程:例如,假设在学习课程 0 前需要先学习课程 1 ,我们用一个先修关系对[0, 1]来表示这种 “后学习课程,先修课程” 的关系。现给定一系列课程与若干先修关系,请判断是否存在一个方案可以学完所有课程

输入格式:输入分为两行,第一行为一个整数,表示课程的总数。第二行为一个嵌套列表的Python表达式,包含若干先修关系对
输出格式:True或False,表示是否存在一个按照先修关系学完所有课程的顺序

输入样例:
2
[[1,0],[0,1]]
输出样例:
False

方法:先用一个列表存储每个课程的先修课程。然后递归判断每一个课是否会产生环

def canFinish(n, course_list, pre):
    if len(course_list) == 0:  # 没有先后修关系,
        return True
    for i in range(len(pre)):  # 得到每门课的所有先修课程
        course_list[pre[i][1]].append(pre[i][0])

    i = 0
    while i < n:  # 依次找到每个点的路径
        visited = []  # 已经探查过的点
        path = []  # 当前探查的点的路径
        if judge_circle(i, visited, path):  # 如果有环
            return False
        i = i+1
    else:
        return True


# 使用递归 判断是否有环
def judge_circle(n, visited, path):
    visited.append(n)
    if n in path:  # 当前点在路径中,说明有环了
        return True
    path.append(n)
    pre_course = course_list[n]  # 当前课程的先修课程
    if not pre_course:  # 如果先修课程是空的 没有环
        return False
    # 依次探索该点的每一个先修课程
    for course in pre_course:
        if course in visited and course not in path:  # 已经探索过而且这个课之前没有出现在path里 说明没有环
            continue
        if judge_circle(course, visited, path):  # 有环
            return True
        path.pop()  # 把探查的课都从路径中去掉
    else:
        return False  # 没有环


n = int(input())  # 输入课程数量
pre = eval(input())  # 输入先修课程关系
course_list = [[] for _ in range(n)]  # 存储课程和先修课程
print(canFinish(n, course_list, pre))

3.2 联网的服务器

题目内容:
   给定一个二维列表表示的地图,其中每个位置值为 1 或 0 ;1 代表该位置存在一个服务器,0 代表该位置为空。对每个服务器来说,如果其所在的位置同一行或同一列有其它服务器,就称这个服务器是“联网”的。请求出地图上所有联网的服务器的总数。

输入格式:一行,为一个以合法Python表达式给出的二维嵌套列表
输出格式:一行整数

输入样例:
[[1,1,0,0],[0,0,1,0],[0,0,1,0],[0,0,0,1]]
输出样例:
4

方法:两个列表分别存储行,列服务器的数量。遍历每一个点,如果当前点是服务器的话,查看行列是否有服务器

代码

def count_connect_server(server_map):
    row = len(server_map)
    col = len(server_map[0])
    row_list = [0]*row  # 记录各行有多少服务器
    col_list = [0]*col  # 记录各列有多少服务器
    for i in range(row):  # 取行号
        for j in range(col):  # 取列号
            if server_map[i][j] == 1:  # 如果当前点是服务器
                row_list[i] += 1
                col_list[j] += 1

    count = 0 # 记录有多少联网服务器
    for i in range(row):
        for j in range(col):
            if server_map[i][j] == 1:  # 如果当前点是服务器
                if max(row_list[i], col_list[j]) > 1:  # 有别的服务器
                    count += 1
    return count


server_map = eval(input())
print(count_connect_server(server_map))
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值