📌  相关文章
📜  门| Sudo GATE 2020 Mock III(2019 年 1 月 24 日)|问题 12(1)

📅  最后修改于: 2023-12-03 14:58:33.716000             🧑  作者: Mango

题目描述

给定一个平面图,每个节点表示一个房间,每个节点上方是一扇门。你在其中一个房间里,你需要穿过所有门离开这个图。每个房间只能进入一次。找到你需要走过的最小路径长度。

示例

例如,下图中,如果你从左上角的房间开始,你需要走过 2+3+1+2 = 8 的长度。注意到最优路径是不唯一的

door_image

输入

输入文件的第一行包含一个整数 t,表示测试用例的数量。每个测试用例以一个正整数 n(2≤n≤500)开头,它表示平面图里面节点的数量。接下来的 n 行中的第 i 行描述了第 i 个房间的位置 xy(-10000≤x,y≤10000)。

输出

对于每个测试用例,输出一个整数表示你需要走过的最短路径长度。只要你的答案与标准答案之间的相对误差小于 10−9,它将被视为正确答案。要注意答案可能溢出 32 位整数。

程序员介绍

这是一道经典的图论题目,要求我们在给定的平面图中,找到从某个起点出发,经过所有的门到达最终的终点的最短路径。由于每个房间只能进入一次,因此我们需要考虑所有可能的路径,找到其中的最短路径。

一种直观的解决方案是采用回溯的思想,枚举所有的可能路径,从中找到最小的路径长度。但是这种方法要求我们枚举指数级别的路径数量,因此在数据量较大的情况下,时间复杂度过高,无法通过本题。

更优秀的解决方案是采用图论的算法。可以将所有的门看作图中的节点,将两个节点之间的距离看作边的权重,问题就转化成了在这个图上找到包含所有节点的最短路径。这是著名的“旅行商问题”,属于NP完全问题,目前还没有找到有效的多项式时间的算法来解决它。因此,在实际情况下,我们只能采用近似算法,或者启发式算法来求解。

常见的求解“旅行商问题”的启发式算法包括遗传算法、模拟退火等。在本题中,我们可以采用“对偶图”的思想来寻找近似解。对于一个图G,它的“对偶图”是由所有的面组成的图,其中每个面都对应了一个点。如果两个面相邻,则这两个点之间连有一条边。如果面的边界组成了一个环,则这个面的点本身在对偶图上形成了一个圆圈。对于一张平面图,它的对偶图就是所有面的各自之间的连接关系的图。例如,对于下图中的矩形,它的对偶图就是中间那个点。

dual_graph_image

对于我们的问题,我们可以将所有的门看作图中的面,将相邻的门之间连上边,这样就构建出了它的对偶图。我们可以通过对偶图上的欧拉回路来寻找到必须经过所有门的一条路径。由于对偶图的欧拉回路很容易找到,因此这种方法的时间复杂度只有O(nlogn)。

代码片段

下面是通过对偶图思想实现的伪代码演示:

ans = 0
for each test case:
    对输入的平面点和门进行连接,构建对偶图
    找到对偶图上的欧拉回路
    根据欧拉回路计算实际路径长度
    更新答案ans
output ans