BFS模板
from collections import deque
graph = graph
start = start
visited = set() # 储存已经访问过的节点
queue = deque([start]) # 创建一个队列并将起点加入其中
visited.add(start) # 将起点标记为已访问
while queue: # 当队列不为空时执行循环
cur = queue.popleft() # 取出队首元素
print(cur) # 访问当前节点
if cur in graph:
for neighbor in graph[cur]: # 遍历当前节点的所有相邻节点
if neighbor not in visited: # 如果相邻节点未被访问过
queue.append(neighbor) # 将其加入队列尾部
visited.add(neighbor) # 并将其标记为已访问过
DFS模板
visited = []
def dfs(node):
"""深度优先搜索遍历树/图的函数"""
# 先将当前节点标记为已访问,并进行相关操作
print(node)
visited.append(node)
# 针对当前节点的所有邻居/子节点进行递归
if node not in graph:
return
else:
for neighbor in graph[node]:
# 判断该节点是否被访问过,如果没被访问过就递归访问它
if neighbor not in visited:
dfs(neighbor)
# 在主程序中调用dfs函数并传入起始节点
dfs(node)
DP模板
N = '列数'
M = '行数'
dp = [[0] * (N+1) for _ in range(M+1)]
for i in range(1, M+1):
for j in range(1, N+1):
if '判断条件':
dp[i][j] = max(dp[i-1][j], dp[i][j-1])
else:
dp[i][j] = xxxx
01背包
def test():
weight = '物品重量列表'
value = '物品价值列表'
bag_weight = '背包容量'
# 初始化: 全为0
dp = [0] * (bag_weight + 1)
# 先遍历物品, 再遍历背包容量
for i in range(len(weight)):
for j in range(bag_weight, weight[i] - 1, -1):
# 递归公式
dp[j] = max(dp[j], dp[j - weight[i]] + value[i])
print(dp)
test()
并查集模板
def root(x):
# 查找x的根节点
if p[x]!=x:
# 如果发现x的根节点不是自己
p[x]=root(p[x])
# 递归找x的根节点,直到找到最原始的根节点为止
return p[x]
# 返回根节点(根节点上面没根节点,自己是根节点)
def union(x,y):
# 合并两个结点
if root(x)!=root(y):
# 如果根节点不同
p[root(x)]=root(y)
# 根节点x指向根节点y
Dijkstra模板
class Dijkstra:
def __init__(self, graph, start, goal):
self.graph = graph # 邻接表
self.start = start # 起点
self.goal = goal
self.open_list = {} # open 表
self.closed_list = {} # closed 表
self.open_list[start] = 0.0 # 将起点放入 open_list 中
self.parent = {start: None} # 存储节点的父子关系 键为子节点, 值为父节点
self.min_dis = None # 最短路径的长度
def shortest_path(self):
while True:
if self.open_list is None:
print('搜索失败, 结束')
break
distance, min_node = min(zip(self.open_list.values(), self.open_list.keys()))
# 取出距离最小的节点
self.open_list.pop(min_node) # 将其从 open_list 中去除
self.closed_list[min_node] = distance # 将节点加入 closed_list 中
if min_node == self.goal: # 如果节点为终点
self.min_dis = distance
shortest_path = [self.goal] # 记录从终点回溯的路径
father_node = self.parent[self.goal]
while father_node != self.start:
shortest_path.append(father_node)
father_node = self.parent[father_node]
shortest_path.append(self.start)
print(shortest_path[::-1]) # 逆序
print('最短路径的长度为: %s' % str(self.min_dis)) # 输出
print('找到最短路径, 结束')
return shortest_path[::-1], self.min_dis # 返回最短路径和最短路径长度
for node in self.graph[min_node].keys(): # 遍历当前节点的邻接节点
if node not in self.closed_list.keys(): # 邻接节点不在 closed_list 中
if node in self.open_list.keys(): # 如果节点在 open_list 中
if self.graph[min_node][node] + distance < self.open_list[node]:
self.open_list[node] = distance + self.graph[min_node][node]
# 更新节点的值
self.parent[node] = min_node # 更新继承关系
else: # 如果节点不在 open_list 中
self.open_list[node] = distance + self.graph[min_node][node]
# 计算节点的值, 并加入 open_list 中
self.parent[node] = min_node # 更新继承关系
if __name__ == '__main__':
graph = {'1': {'2': 2, '4': 1},
'2': {'4': 3, '5': 11},
'3': {'1': 4, '6': 5},
'4': {'3': 2, '6': 8, '7': 4, '5': 2},
'5': {'7': 6},
'7': {'6': 1}}
start = '1'
goal = '6'
dijk = Dijkstra(graph, start, goal)
dijk.shortest_path()
Floyd模板
from sys import setrecursionlimit
setrecursionlimit = 10e10
def Floyd():
n = len(graph)
for k in range(n):
for i in range(n):
for j in range(n):
if graph[i][k] + graph[k][j] < graph[i][j]:
graph[i][j] = graph[i][k] + graph[k][j]
parents[i][j] = parents[k][j] # 更新父节点
# 输出
def return_path(i,j):
if i != j: return_path(i,parents[i][j])
print(j, end = '-->')
# 数据定义
# Data [u,v,cost]
datas = [
[0, 1, 2],
[0, 2, 6],
[0, 3, 4],
[1, 2, 3],
[2, 0, 7],
[2, 3, 1],
[3, 0, 5],
[3, 2, 12]
]
n = 4
# 构图
graph=[[(lambda x: 0 if x[0] == x[1] else float('inf'))([i,j]) for j in range(n)] for i in range(n)]
parents=[[i] * n for i in range(4)] # 关键点: i-->j 的父节点初始化都为i
for u,v,c in datas:
graph[u][v] = c # 因为是有向图, 边权只赋给graph[u][v]
# graph[v][u] = c # 如果是无向图, 要加上这条
# 主函数
Floyd()
# 输出
print('Costs:')
for row in graph:
for e in row:
print('∞' if e == float('inf') else e, end='\t')
print()
print('\nPath:')
for i in range(n):
for j in range(n):
print('Path(%d-->%d): ' % (i,j),end='')
return_path(i,j)
print(' cost:',graph[i][j])