我有一个带有N个veritces和M个边的加权无向图。每个边缘都有它的重量和颜色。整个图表中最多有10种不同的颜色。每当我通过不同颜色的边缘时,我必须支付额外费用等于K.给定两个顶点A和B,我想找到它们之间的最短路径。例如,给定具有3个顶点的多图,K = 5和3个边:( 1 - > 2的重量3和颜色1),(1 - > 2的重量5和颜色2),(2 - > 3个权重2和颜色2),最短路径的权重是12.我想设计一个能在相当长的时间内解决这个问题的算法(类似于O(N)或O(N log N)),但我除了暴力之外别无所求。
我仍在寻找解决方案。如果有人知道如何解决,请回复。
约束:
N <= 10 ^ 5
M <= 10 ^ 5
K <= 10 ^ 5
答案 0 :(得分:2)
对于每个顶点,根据您到达它的颜色将其拆分为10个不同的顶点(每个副本的输出边缘相同)。请注意,即使原始图形是无向的,也会定向此新图形。
然后Dijkstra在这个新图中的算法给出了答案。
答案 1 :(得分:1)
我说你可以修改Dijkstra's Algorithm来做到这一点。您只需为每个顶点存储一个额外的字段,以便传递最后一个颜色,这样当算法需要边长时,您可以在该边的颜色不等于最后传递的颜色时添加颜色税。然后你必须更新那个领域。这将在O(M + N log N)时间内完成。
编辑:使用伪代码:
1 function Dijkstra(Graph, source):
2 dist[source] ← 0
3
4 create vertex set Q
5
6 for each vertex v in Graph:
7 if v ≠ source
8 dist[v] ← INFINITY
9 prev[v] ← UNDEFINED
11 Q.add_with_priority(v, dist[v])
12
13 while Q is not empty:
14 u ← Q.extract_min()
15 for each neighbor v of u:
16 if color(prev[u], u) ≠ color(u, v)
17 alt = dist[u] + length(u, v) + colorTax
18 else
19 alt = dist[u] + length(u, v)
20 if alt < dist[v]
21 dist[v] ← alt
22 prev[v] ← u
23 Q.decrease_priority(v, alt)
24
25 return dist[], prev[]
事实证明,通过使用prev-field,甚至不需要新的领域。