让我们得到N个没有边的Verticle图。
让我们有边缘列表:
x1 y1
x2 y2
x3 y3
.
.
.
xk yk
我们必须处理从1到k的所有边。 我们不得不说第x个边是否在图中形成循环。如果不是,请将其添加到图表中。
如何有效地做这样的事情?我的意思是不检查DFS是否每次都在制作一个循环图。
有更快的东西吗? 这是波兰的SPOJ问题
https://pl.spoj.pl/problems/XIWTPZF/
感谢您的帮助。 克里斯
答案 0 :(得分:1)
创建边缘对象。在edge对象中,您有两个标志。跟踪标志和添加的标志。 从要检查的边列表构建对象模型。添加所有边,并使用边对象中的指针连接链接的边。向模型添加边时,链接到新添加的边,所有先前添加的边以新添加的边的起点结束。
测试边缘时,首先暂时设置它的添加标记。然后递归跟踪,随时设置跟踪标志。如果碰撞已经跟踪的边缘,则返回false,并在出路时清除跟踪标记。重要的是你没有追踪没有设置添加标志的边缘。
如果没有发生碰撞,则对于每个终止边缘都返回true,而不会触及跟踪标记。
如果返回true,则移至有序列表中的下一个边缘。如果返回false,则清除添加的标志。
在跟踪结束时,检查添加的标记。
在这个位置严重伪装代码(所以不要更正我的C ++语法):http://pastebin.com/dT2bFmqp
答案 1 :(得分:0)
总的来说,我不确定这样做的有效方法。我认为通过将图形划分为不相交的集合可以获得一些效率,但这实际上取决于特定输入图表的布局,这将取决于您将获得多少。此外,您可以采取其他一些快捷方式(例如检查您要连接的边缘是否有任何边缘),但这又取决于特定图表的属性是否会对您有所帮助。< / p>
这是我提出的算法,可能没有您想要的效率:
# No cycles on an empty list
for edge in edgeList:
graph.addEdge(edge)
cycles = detectCycle(graph)
if cycles
graph.removeEdge(edge)