关于图的基本概念,简单的过一遍吧
图的分类(简单图:没有自环和复边):有向图,无向图
图的常用的存储结构:邻接矩阵,邻接表
图的性质:度,出度,入度
图的遍历方式:深度优先遍历,广度优先遍历
图的应用:最短路径,拓扑排序等
1.关于图的邻接矩阵的性质
图的邻接矩阵A相乘,比如 B = A^n 第 i 行第 j 列的值表示节点 i 到节点 j 的长度为 n 路径共有 B[i][j] 条。
如:LCP 07 传递信息
深度优先遍历
class Solution:
def numWays(self, n: int, relation: List[List[int]], k: int) -> int:
self.dic = {}
self.res = 0
for i in range(n):
self.dic[i] = []
for a, b in relation:
self.dic[a].append(b)
self.dfs(0, 0, k, n)
return self.res
def dfs(self, tmp, cur, k, n):
if tmp==k:
if cur == n-1:
self.res += 1
return
for c in self.dic[cur]:
self.dfs(tmp+1, c, k, n)
邻接矩阵
import copy
class Solution:
def numWays(self, n: int, relation, k: int) -> int:
matrix = [[0 for i in range(n)] for j in range(n)]
for tmp in relation:
matrix[tmp[0]][tmp[1]] = 1
A = copy.deepcopy(matrix)
for p in range(k-1):
cur = copy.deepcopy(matrix)
for i in range(n):
for j in range(n):
matrix[i][j] = sum([cur[i][q]*A[q][j] for q in range(n)])
return matrix[0][n-1]
2. 二分图
1) 涂色:遍历顶点,若当前顶点涂色,若其邻接顶点未涂色则给邻接顶点涂相反色;若邻接顶点已涂色,且与当前顶点同色,则不是二分图,遍历完未出现同色则是二分图。
2)根据无向图G为二分图的充分必要条件是,G至少有两个顶点,且其所有回路的长度均为偶数。判断是否有奇数环,如果才能在奇数环则不是二分图。
深度优先遍历:
class Solution:
def isBipartite(self, graph) -> bool:
n = len(graph)
visited = [-1 for i in range(n)]
for i in range(n):
if visited[i] == -1:
if not self.dfs(i, 0, graph, visited):
return False
return True
def dfs(self, cur, color, graph, visited):
visited[cur] = color
for i in graph[cur]:
if visited[i] == -1:
if not self.dfs(i, 1 - color, graph, visited):
return False
elif visited[i] == visited[cur]:
return False
return True
广度优先遍历:
class Solution:
def isBipartite(self, graph) -> bool:
n = len(graph)
visited = [-1 for i in range(n)]
for i in range(n):
if visited[i] == -1:
visited[i], color = 0, 0
queue = graph[i]
while len(queue)!=0:
m = len(queue)
for k in range(m):
j = queue.pop()
if visited[j] == -1:
visited[j] = 1 - color
queue.insert(0, j)
elif visited[j] == color:
return False
color = 1 - color
return True