C++ 连通图中边的去除算法

C++ 连通图中边的去除算法,c++,algorithm,C++,Algorithm,问题: 你有一个连通的,不是有向的图。有N个顶点。您还有一个结构数组: struct Edge { int a; int b; } 数组StructArray表示所有边。数组的大小为M。找到最小k,以便在从StructArray中删除除边[0…k-1]以外的所有边后,图形仍保持连接 我的想法 我不知道如何处理此结构,因此我正在重建它(这可能是一种非常糟糕的方法),以创建邻接列表: vector < vector <int> > edges_list(

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

struct Edge
{
     int a;
     int b;
}
数组StructArray表示所有边。数组的大小为M。找到最小k,以便在从StructArray中删除除边[0…k-1]以外的所有边后,图形仍保持连接

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

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

你觉得这个解决方案怎么样?好/坏?你还有别的吗?也许保留结构而不创建新结构?

我会以递增方式而不是递减方式处理此问题:从空图形开始,逐个添加边,直到图形连接。使用不相交的集合数据结构(如中所示)来检测何时只有一个连接的组件。

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

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

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


解决这一问题的一种方法是从任何节点开始,简单地进行深度优先搜索,直到到达所有节点。

这是图论中一个非常著名的问题的变体,称为问题的发现。不同之处在于,在您的问题中,边没有加权。换句话说,所有边都具有相同的权重,这意味着您的问题在某种程度上比原始问题更容易


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

Hmm,最小边数总是N-1(即树中的边数)

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


要找到一组有效的边,只需使用一个简单的或,因为这些搜索总是形成一个连接树(它们不会访问顶点两次!)

我觉得你的方法很好。如果边的数量很大,可以通过将一个向量转换为地图来提高效率;但你可能不会这么做,除非后来证明这很重要。否则,您的方法看起来不错。但例如,如果有1.000.000条边,并且需要所有这些边才能连接图形,那么程序应该在测试第一条边(StructArray[m-1])后立即结束。@Randolph True,但是这种方法的渐近运行时间非常接近线性。您是对的。。。那你知道怎么修吗?
edges_list[a].size() > 1 && edges_list[b].size() > 1;