从给定边缘构建DAG

时间:2011-05-31 20:51:25

标签: graph

让我们得到N个没有边的Verticle图。

让我们有边缘列表:

x1 y1
x2 y2
x3 y3
.
.
.
xk yk

我们必须处理从1到k的所有边。 我们不得不说第x个边是否在图中形成循环。如果不是,请将其添加到图表中。

如何有效地做这样的事情?我的意思是不检查DFS是否每次都在制作一个循环图。

有更快的东西吗? 这是波兰的SPOJ问题

https://pl.spoj.pl/problems/XIWTPZF/

感谢您的帮助。 克里斯

2 个答案:

答案 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)