[Python]邻接矩阵?邻接列表的创建和相互转换[图论]


介绍

在进行竞争性编程时,迟早碰到的墙是"图论"。这次,我总结了用代码在Python中创建"邻接矩阵"和"邻接表"的基本方法。根据问题,请自己动手改造。

邻接矩阵和邻接表

例如,考虑下图。
g.png

计算机上有两种主要类型的图形数据结构。让我们根据情况正确使用它。
一个是隣接行列,其形式为$ n \\乘以n $矩阵。它使用大量内存,但是具有能够确定在恒定时间内是否存在特定边沿的优势。

adj_m.txt

1
2
3
4
5
[[0, 1, 1, 0, 1],
 [1, 0, 1, 1, 0],
 [1, 1, 0, 1, 1],
 [0, 0, 1, 1, 1],
 [1, 0, 1, 1, 0]]

另一个是隣接リスト。尽管它使用较少的内存,但它有一个缺点,即在最坏的情况下需要$ O(V)$来确定是否存在特定的边。

adj_l.txt

1
[[2, 3, 5], [1, 3, 4], [1, 2, 4, 5], [2, 3, 5], [1, 3, 4]]

实际上,经常给出辺の2つの端点,例如AtCoder初学者竞赛168 D ..(双点)。

当我尝试表示该图的输入时,它如下所示。 (在第一行中输入了顶点数n和边数m)

input.txt

1
2
3
4
5
6
7
8
9
5 8
1 2
1 3
1 5
2 3
2 4
3 4
3 5
4 5

Python代码

我将编写输入邻接矩阵和邻接列表转换及其相互转换的备忘单。

输入到邻接表

没有边缘重量时。

1
2
3
4
5
6
7
n, m = map(int, input().split())
graph = [[] for _ in range(n)]
for _ in range(m):
    a, b = map(int, input().split())
    graph[a-1].append(b-1)
    graph[b-1].append(a-1)  # 有向グラフなら消す
print(graph)  # [[2, 3, 5], ..., [1, 3, 4]]

如果有边缘重物。

1
2
3
4
5
6
7
n, m = map(int, input().split())
graph = [[] for _ in range(n)]
for _ in range(n):
    u, v, w = map(int, input().split())
    graph[u-1].append([v-1, w])
    graph[v-1].append([u-1, w])  # 有向グラフなら消す
print(graph)  # [[2, 3], [3, 1], [5, 9]], ..., [...]]

输入到邻接矩阵

没有边缘重量时。

1
2
3
4
5
6
7
n, m = map(int, input().split())
graph = [[0]*n for _ in range(n)]
for _ in range(m):
    a, b = map(int, input().split())
    graph[a-1][b-1] = 1
    graph[b-1][a-1] = 1  # 有向グラフなら消す
print(graph)  # [[0, 1, 1, 0, 1], ..., [1, 0, 1, 1, 0]]

有体重时。

1
2
3
4
5
6
7
n, m = map(int, input().split())
graph = [[0]*n for _ in range(n)]
for _ in range(m):
    u, v, w = map(int, input().split())
    graph[u-1][v-1] = w
    graph[v-1][u-1] = w  # 有向グラフなら消す
print(graph)  # [[0, 2, 3, 0, 1], ..., [2, 0, 3, 0, 0]

邻接表到邻接矩阵

定位没有边缘权重的无向图。
邻接列表是graph,邻接矩阵是graph_new

1
2
3
4
5
graph_new = [[0]*n for _ in range(n)]  # 隣接行列
for i, g_i in enumerate(graph):
    for j in g_i:
        graph_new[i][j] = 1
print(graph_new)

邻接表到邻接表

定位没有边缘权重的无向图。
邻接矩阵是graph,邻接列表是graph_new

1
2
3
4
5
6
7
8
graph_new = []
for i in range(n):
    tmp_l = []
    for j in range(n):
        if graph[i][j] > 0:
            tmp_l.append(j)
    graph_new.append(tmp_l)
print(graph_new)

结论

感谢您的阅读。如果您有任何错误或印刷错误,请告诉我,我们将不胜感激。