📌  相关文章
📜  门| Sudo GATE 2020 Mock II(2019年1月10日)|问题26(1)

📅  最后修改于: 2023-12-03 15:12:45.088000             🧑  作者: Mango

门 | Sudo GATE 2020 Mock II(2019年1月10日)|问题26

介绍

本题考查的是并查集的应用,题目的内容简述如下:有n个点和m条边,每条边连接两个点,并给出其中两个点,要求求出两个点之间的最短距离。其中,点的编号从1到n。

思路

对于此类问题,我们可以使用并查集对图进行预处理。我们可以将每个点看做一个集合,并将他们抽象地看成节点进行处理。然后,通过边的信息将节点之间进行合并(即将两个集合合并成一个集合),通过这个操作,最终合并成一个大的集合。当我们需要查找两点之间的最短距离时,我们可以简单地查找它们的根节点,因为根节点是该集合所有点的代表。通过比较两个点的根节点,我们可以判断它们是否在同一个集合中,如果不在,它们之间的距离为无穷,否则它们之间的距离为它们的深度之和。

代码

下面是使用Python实现的简单示例代码,它使用了一个字典变量pre记录每个集合的根节点的编号以及深度。

class Solution:
    def shortestPath(self, n: int, edges: List[List[int]], x: int, y: int) -> int:
        pre = {}  # 记录每个集合的根节点编号和深度

        # 初始化每个节点所在的集合
        for i in range(1, n+1):
            pre[i] = (-1, 0)  # -1表示它是根节点,0表示深度为0

        # 将边加入并查集
        for edge in edges:
            root1, depth1 = self.findRoot(pre, edge[0])
            root2, depth2 = self.findRoot(pre, edge[1])
            if root1 != root2:  # 如果不在同一个集合中,则把root2并入root1
                pre[root2] = (root1, depth1+depth2+1)

        # 查找x,y的根节点及深度
        root1, depth1 = self.findRoot(pre, x)
        root2, depth2 = self.findRoot(pre, y)

        if root1 != root2:
            return -1  # 如果不在同一个集合中,则返回-1

        return depth1 + depth2  # 否则返回两个节点的深度之和

    def findRoot(self, pre, x):
        # 递归查找x所在的集合的根节点和深度
        if pre[x][0] == -1:
            return x, pre[x][1]
        root, depth = self.findRoot(pre, pre[x][0])
        pre[x] = (root, depth-pre[x][1])  # 路径压缩
        return pre[x]
总结

本题是一道并查集的变种题目,相对于标准的并查集问题,它要求我们求出两个节点之间的最短距离。因此,我们在合并时需要注意记录每个节点所在的集合的深度,并在查找根节点时需要进行路径压缩,以减少时间复杂度。