图表是正加权的,可能是非循环的。
输入文件由
组成顶点数,边数,开始顶点,结束顶点
edge1(从,到,重量)
edge2(从,到,重量) 等等。
如果图中有周期,路径的长度将是无限的,如果没有办法则为0
我这样做的方法是删除长度较短的相同边缘,并在adjecent列表或矩阵中使用bellman ford或dijkstra算法,两者都可以正常工作。
但是,程序应该找到最多2秒的路径,一些输入文件包含10000个顶点和100000个边
我该怎么办?
答案 0 :(得分:0)
时间限制是2秒,这意味着程序应该接近约10 ^ 6次迭代。查看V = 10000
和e = 100000
的限制。这意味着O(V)或O(E)或O(V + E)或甚至O(E + VlogV)
的算法将很容易在给定时间内很好地计算您的需求。
Note E + Vlogv ~ (100000 + ~132877) which is less than 10^6
//对于频率为10 ^ 9 Hz的处理器,此10 ^ 6限制是有效的。因此,即使您的算法每次迭代都有1000条指令,您也将处于安全区域。
所以,这是提出的算法:
您将在O(E)
中构建图表。使用邻接列表数据结构来表示图形。
- >在构建此数据结构时,存储每个顶点的indegree并存储顶点数。
countV := V;
foreach edge_i
inDegree[to] := inDegree[to] + 1;
检查O(V + E)
中图表中是否有周期。
if no vertex with indegree = 0 and countV = 0
graph has no cycle
else if no vertex with indegree = 0 and countV != 0
graph has cycle
else select any vertex having 0 indegree
countV := countV - 1;
decrease all its directed neighbours' inDegree by 1.
因此,如果你得到一个循环,你的答案是无限的。
制作BFS或DFS以获取ending vertex
是否可以从beginning vertex
到达。这可以在O(V + E)
甚至O(E)
中完成。我们来看O(V + E)
。如果无法访问,您的答案将直接为0。
现在,申请dijkstra但是在放松的情况下,请检查相反的情况。即在给出here的伪代码中,而不是
if alt < dist[v]:
dist[v] := alt;
DO
if alt > dist[v]:
dist[v] := alt;
这可以在O(E + VlogV)
中完成。因此,解决方案的总体复杂性将是O(E + VlogV)
,这在约束条件下是很好的。