我在比赛的某个地方发现了这个问题,但还没有找到解决方案。我正在考虑应用Dijkstra的东西,但不是很清楚:
''您将获得一个城市的加权连通图,其中所有边都具有正权重。一些城市(节点)有汽油泵,而有些城市没有。你有一辆坦克容量为C的自行车。也就是说,有了满箱,汽车可以行驶C单位的距离。在任何有汽油泵的城市,汽车都可以将其油箱装满。找出给定源和给定目标之间的最短路径。假设你从一个满罐开始。''
我有一种感觉O(mn logn)将被它接受。
答案 0 :(得分:3)
基本上你需要根据自行车到达时的剩余燃料将每个节点n_i拆分为多个节点,让我们称之为(n_i,r)。你不需要在开头创建所有(n_i,r),你可以在飞行中创建它。
然后类似于Dijkstra,你从节点(n_0,C)开始,每次你可以找到下一个(n_x,r)你可以达到最小距离。并更新连接到(n_x,r)的所有节点(n_y,ry)。如果n_y有泵,ry将被重置为C.如果对于n_y,已经存在节点(n_y,r)和r> = ry,那么您不需要创建新节点(n_y,ry),只需忽略它。
我不能说运行时的复杂性,但它应该足以让AC参加比赛。
答案 1 :(得分:3)
@Tim Green的方法将创建一个指数(加油站数量)节点数。运行Dijkstra的速度非常慢。有一种更快的方式。
首先,找到所有加油站之间的距离。还包括从源到每个加油站,从每个加油站到终点,从源到终点的距离。这可以通过多次运行Dijkstra's来完成。
这将为您提供从开始到结束的所有可能有效路线的图表。只需在此图表上再次运行Dijktra即可获得最终解决方案。
由于Dijkstra的每次运行都是 O(V 2 ) (V =城市数量),你必须运行它 O(G)次(G =加油站数量,一次运行Djikstra可以找到从一个加油站到所有其他加油站的距离),此算法将在< strong> O(V 2 G)时间。
答案 2 :(得分:2)
对Dijkstra算法进行了修改,加油站顶点之间的距离是根据需要通过Dijkstra算法的另一个修改来计算的,该算法搜索指定范围内的所有未解析的加油站顶点。
main-Dijkstra在循环中执行以下步骤:
0.当主要优先级队列为空时退出&#34;完成无法到达&#34;
1.从主要优先队列中取出加油站
2.完成后退出。
3.致电sub-Dijkstra,为未解决的邻近加油站提供与实际加油站的距离。
sub-Dijkstra使用自己的优先级队列(直到队列为空)搜索从实际加油站到燃料范围内所有顶点的最短路径,并根据其状态处理到达的加油站:
*已在main中解决 - 不处理外发边缘
*在主队列中等待 - 更新距离(当低于reduceKey时)和路径
*否则将其放入主队列