搜索与图论
排列数字
#版本一
n = int(input())
v = []
st = [0] * (n + 1)
def dfs(cnt: int):
if cnt == n + 1:
for tmp in v:
print(tmp, end = ' ')
print()
else:
for i in range(1, n + 1):
if st[i] == 0:
st[i] = 1
v.append(i)
dfs(cnt + 1)
st[i] = 0
v.pop()
dfs(1)
#版本二
n = int(input())
v = []
st = [0] * (n + 1)
def dfs(cnt: int):
if cnt == n + 1:
print(' '.join(list(map(str,v))))
else:
for i in range(1, n + 1):
if st[i] == 0:
st[i] = 1
v.append(i)
dfs(cnt + 1)
st[i] = 0
v.pop()
dfs(1)
#list(map(str,v))) 将 v 中元素类型进行转换为 str ,
# ’seq‘.join(lst) 将 list 中的元素进行拼接,注意 list 中或者其他元组的数据类型需要时 str 类型,各个元素之间的分隔符为 seq
N-皇后
n = int(input())
def prints(cols: list):
ans = [['.'] * n for _ in range(n)]
for r, c in enumerate(cols):
ans[r][c] = 'Q'
for i in range(n):
print("".join(ans[i]))
print()
col = []
st = [False] * n
def dfs(cur: int):
if cur == n:
prints(col)
return
for tmp in range(n):
if st[tmp] == True:
continue
col.append(tmp)
st[tmp] = True
flag = 1
for i in range(len(col) - 1):
if col[i] + i == col[cur] + cur or col[i] - i == col[cur] - cur:
flag = 0
break
if flag == 1:
dfs(cur + 1)
col.pop()
st[tmp] = False
dfs(0)
迷宫问题
from collections import deque
n, m = map(int, input().split())
idx = [-1, 1, 0, 0]
idy = [0, 0, -1, 1]
st = [[0] * m for _ in range(n)]
st[0][0] = 1
G = [list(map(int, input().split())) for _ in range(n)]
def bfs():
q = deque()
q.append(((0, 0), 0))
while q:
cur = q.popleft()
x, y, step = cur[0][0], cur[0][1], cur[1]
if x == n - 1 and y == m - 1:
return step
for i in range(4):
nx, ny = x + idx[i], y + idy[i]
if 0 <= nx < n and 0 <= ny < m and st[nx][ny] == 0 and G[nx][ny] == 0:
st[nx][ny] = 1
q.append(((nx, ny), step + 1))
print(bfs())
八数码
from collections import deque
string = input().replace(" ", "")
end = "".join(sorted(string))
def bfs():
q = deque()
q.append(string)
dx, dy = [1, -1, 0, 0], [0, 0, 1, -1]
table = {string: 0}
while q:
p = q.popleft()
if end in table:
return table[end]
idx = p.find('x')
x, y = idx//3, idx%3
for i in range(4):
a, b = x + dx[i], y + dy[i]
if a >=0 and a < 3 and b >= 0 and b < 3:
ii = a * 3 + b
pp = p[:idx] + p[ii] + p[idx + 1:]
pp = pp[:ii] + 'x' + pp[ii + 1:]
if pp not in table:
table[pp] = table[p] + 1
q.append(pp)
return -1
print(bfs())
图的层次遍历
from collections import deque
from collections import defaultdict
n, m = map(int, input().split())
G = defaultdict(int)
for _ in range(m):
u, v = map(int, input().split())
if u not in G:
G[u] =[v]
else:
G[u].append(v)
q = deque()
q.append([1, 0])
st = [False] * (n + 1)
flag = 1
while q:
cur = q.popleft()
u, step = cur[0], cur[1]
if u == n:
print(step)
flag = 0
break
st[u] = True
if G[u]:
for v in G[u]:
if st[v] == False:
q.append([v, step + 1])
if flag: print(-1)
拓扑排序
from collections import defaultdict
from collections import deque
n, m = map(int, input().split())
G = defaultdict(int)
deg = [0] * (n + 1)
for _ in range(m):
x, y = map(int, input().split())
deg[y] += 1
if x not in G:
G[x] = [y]
else:
G[x].append(y)
q = deque()
ans = []
for u in range(1, n + 1, 1):
if deg[u] == 0:
q.append(u)
while q:
u = q.popleft()
ans.append(u)
if G[u]:
for v in G[u]:
deg[v] -= 1
if deg[v] == 0:
q.append(v)
if len(ans) == n:
print(" ".join(map(str, ans)))
else:
print(-1)
#版本二
from collections import defaultdict
from collections import deque
n, m = map(int, input().split())
G = defaultdict(int)
deg = [0] * (n + 1)
for _ in range(m):
x, y = map(int, input().split())
deg[y] += 1
if x not in G:
G[x] = [y]
else:
G[x].append(y)
ans = []
q = [i for i in range(1, n + 1, 1) if not deg[i]]
while q:
u = q.pop(0)
ans.append(u)
if G[u]:
for v in G[u]:
deg[v] -= 1
if deg[v] == 0:
q.append(v)
if len(ans) == n:
print(" ".join(map(str, ans)))
else:
print(-1)
dij I II
from collections import deque
from collections import defaultdict
import heapq
n, m = map(int, input().split())
INF = 10 ** 9
G = defaultdict(list)
for _ in range(m):
x, y, w = map(int, input().split())
G[x].append((y, w))
def dij() -> int:
dist = [INF for _ in range(n + 1)]
dist[1] = 0
minHeap = []
vis = [False for _ in range(n + 1)]
heapq.heappush(minHeap, (0, 1))
while minHeap:
w, u = heapq.heappop(minHeap)
if vis[u] == True:
continue
vis[u] = True
for v, cost in G[u]:
if dist[v] > dist[u] + cost:
dist[v] = dist[u] + cost
heapq.heappush(minHeap, (dist[v], v))
return dist[n]
res = dij()
print(-1) if res == INF else print(res)
有边数限制的最短路
# 写法一
n, m, k = map(int, input().split())
Edges = []
for _ in range(m):
u, v, d = map(int, input().split())
Edges.append([u, v, d])
INF = 10 ** 9
dis = [0, 0] + [INF] * (n)
for _ in range(k) :
dis_copy = dis.copy()
for i in range(m) :
u, v, w = Edges[i]
dis[v] = min(dis[v], dis_copy[u] + w)
print(dis[n]) if dis[n] < INF // 2 else print("impossible")
#写法二
n, m, k = map(int, input().split())
Edges = []
for _ in range(m):
u, v, d = map(int, input().split())
Edges.append([u, v, d])
INF = 10 ** 9
dis = [0, 0] + [float('inf')] * (n)
for _ in range(k):
dis_cop = dis.copy()
for u, v, w in Edges:
dis[v] = min(dis[v], dis_cop[u] + w)
print(dis[n]) if dis[n] != float('inf') else print("impossible")
spfa
from collections import deque
n, m = map(int, input().split())
G = [[] for _ in range(n + 5)]
for _ in range(m):
u, v, w = map(int, input().split())
G[u].append((v, w))
dis = [float('inf')] * (n + 1)
vis = [False] * (n + 1)
def spaf(s):
q = deque()
q.append(s)
dis[s] = 0
while q:
u = q.popleft()
vis[u] = False
for v, w in G[u]:
if dis[v] > dis[u] + w:
dis[v] = dis[u] + w
if vis[v] == False:
vis[v] = True
q.append(v)
spaf(1)
print(dis[n]) if dis[n] != float('inf') else print("impossible")
spaf 判负环
from collections import deque
import sys
line = list(sys.stdin.readline().strip().split())
n, m = map(int, line)
G = [[] * (n + 1) for _ in range(n + 1)]
for _ in range(m):
line = list(sys.stdin.readline().strip().split())
u, v, w = map(int, line)
G[u].append([v, w])
vis = [False] * (n + 1)
dis = [float('inf')] * (n + 1)
cnt, st= [0] * (n + 1), [False] * (n + 1)
def spaf(s):
dis[s] = 0
q = deque()
q.append(s)
while q:
u = q.popleft()
st[u] = False
vis[u] = True
for v, w in G[u]:
if dis[v] >dis[u] + w:
dis[v] = dis[u] + w
cnt[v] += 1
if cnt[v] > n:
return True
if st[v] == False:
st[v] = True
q.append(v)
return False
flag = 1
for i in range(1, n + 1, 1):
if vis[i] == True:
continue
if spaf(i) == True:
print("Yes")
flag = 0
break
if flag: print("No")
floyd
n, m, q = map(int, input().split())
G = [[float('inf')] * (n + 1) for _ in range(n + 1)]
for _ in range(m):
x, y, w = map(int, input().split())
G[x][y] = min(G[x][y], w)
for _ in range(n + 1):
G[_][_] = 0
for k in range(n + 1):
for i in range(n + 1):
for j in range(n + 1):
G[i][j] = min(G[i][j], G[i][k] + G[k][j])
for _ in range(q):
u, v = map(int, input().split())
print(G[u][v]) if G[u][v] != float('inf') else print("impossible")
Kruskal最小生成树
#写法1
from collections import defaultdict
import sys
from collections import namedtuple
if __name__ == '__main__':
n, m = map(int, input().split())
Edge = namedtuple('edge', ('start', 'end', "w"))
G = []
for _ in range(m):
u, v, w = map(int, input().split())
G.append(Edge(u, v, w))
G = sorted(G, key = lambda edge: edge.w, reverse = True)
res = 0
count = 0
p = [i for i in range(n + 1)]
def find(k):
if k != p[k]:
p[k] = find(p[k])
return p[k]
for edge in G:
pa = find(edge.start)
pb = find(edge.end)
#print(pa, pb)
if pa != pb:
p[pa] = pb
res += edge.w
count += 1
if count < n - 1:
print('impossible')
else:
print(res)
# 类结构体
# u, v, w
G.append([u, v, w])
G.append((u, v, w))
#类结构体排序
G.sort(key = lambda x: x[2]) # 按照第三个关键字进行排序
G = sorted(G, key = lambda a: a[2]) #默认都是升序、降序加上 reverse = True
#写法2
n, m = map(int, input().split())
G = []
for _ in range(m):
u, v, w = map(int, input().split())
G.append([u, v, w])
G.sort(key = lambda x: x[2])
res = 0
fa = [i for i in range(n + 1)]
def find(k):
fa[k] = fa[k] if fa[k] == k else find(fa[k])
return fa[k]
count = 0
for i in range(m):
fax, fay = find(G[i][0]), find(G[i][1])
if fax != fay:
count += 1
fa[fax] =fay
res += G[i][2]
if count == (n - 1): print(res)
else: print('impossible')
染色法判断二分图
from collections import deque
n, m = map(int, input().split())
G = [[] for _ in range(n + 1)]
for _ in range(m):
u, v = map(int, input().split())
G[u].append(v)
G[v].append(u)
col = [0] * (n + 1)
def bfs(s, c):
q = deque()
q.append(s)
col[s] = c
while q:
u = q.popleft()
tmpc = col[u]
for v in G[u]:
if col[v] == 0:
col[v] = -tmpc
q.append(v)
elif col[v] == tmpc:
return False
return True
res = True
for i in range(1, n + 1, 1):
if col[i] == 0:
res = bfs(i, 1)
if res == False:
break
print("Yes") if res else print("No")
二分图最大匹配
n1, n2, m = map(int, input().split())
n = n2 + n1 + 1
G = [[] * n for _ in range(n)]
for _ in range(m):
u, v = map(int, input().split())
G[u].append(v)
match = [0 for _ in range(n2 + 1)]
def find(i):
for j in G[i]:
if not st[j]:
st[j] = True
if not match[j] or find(match[j]):
match[j] = i
return True
return False
res = 0
for i in range(1, n1 + 1):
st = [False] * (n2 + 1)
if find(i):
res += 1
print(res)