用于去除连通图中的边的算法

时间:2014-09-11 18:01:00

标签: c++ algorithm

问题: 你有一个连接的,而不是有向图。有N个顶点。你还有一个结构数组:

struct Edge
{
     int a;
     int b;
}

数组StructArray表示所有边。数组的大小为M.找到最小k,以便在从StructArray移除除了那些边之外的所有边之后:[0 ... k-1],图形仍然连接。

我的想法 我不知道如何处理这个结构,所以我正在重建它(这可能是一个非常糟糕的方法),创建一个邻接列表:

vector < vector <int> > edges_list(N);

现在从StructArray的末尾开始,每次要删除边时,都要检查edges_list:

edges_list[a].size() > 1 && edges_list[b].size() > 1;

您对此解决方案有何看法?这好/坏?你还有其他吗?也许保持结构,而不是创建一个新结构?

4 个答案:

答案 0 :(得分:1)

我会逐步而不是递减地处理这个问题:从空图开始,逐个添加边,直到连接图。使用Kruskal's algorithm中的不相交集数据结构来检测何时只有一个连接的组件。

答案 1 :(得分:1)

这是图论中一个众所周知的问题的变体,称为Minimum Spanning Tree问题的发现。变化是在你的问题中边缘没有加权。换句话说,你的所有边都具有相同的权重,这意味着你的问题在某种程度上比原来的更容易。

解决此问题的两种最常用的算法是Prim's algorithmKruskal's algorithm(David Eisenstat提到)。阅读有关问题和其中一种算法(我个人认为Prim的算法更直观),并尝试实现它(或在网上找到现有的实现,我相信它们有很多!)。

答案 2 :(得分:0)

我认为创建邻接列表是个好主意。

但是,我不认为算法是正确的。假设你有A连接到B,B连接到C,C连接到D.我认为你的算法会错误地认为它可以删除边B到C,但这实际上断开了图。

这是一个标准问题,称为查找生成树。

修复它的一种方法是从任何节点开始,只需进行深度优先搜索,直到到达所有节点。

答案 3 :(得分:0)

嗯,最小边数总是N - 1,(这是树中边的数量)

因此,如果您只想找到k,答案是N - 1。

要查找有效的边集,只需使用简单的BFSDFS,因为这些搜索始终会形成连接树(它们永远不会访问顶点两次!)