十二、图及算法-下
本系列博客基于“ (北京大学)数据结构与算法python版”慕课,课程在中国大学慕课和bilibili上均可找到。
1. 内容
- 深度优先搜索DFS算法
- 图的应用:拓扑排序,强连通分支,最短路径,最小生成树,
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))