测试连接的图形

Test for connected graph

本文关键字:图形 连接 测试      更新时间:2023-10-16

我实现了一种联合查找算法,该算法查找并连接具有由整数表示的顶点的无向图。我想知道是否有人有任何伪代码或关于如何查看组件是否"连接"的想法,即有一个从一个节点到另一个节点的路径。例如,我有以下顶点:

7(源顶点)、9(目标顶点)和 8(源顶点)、7(目标顶点)都已连接。但是,像 3(源顶点)、5(目标顶点)之类的东西不会连接到前一组组件。谁能指导我朝着正确的方向前进,或者给我一个关于如何测试它的想法?谢谢!

是的,您要做的就是测试两个节点是否具有相同的根。 如果在构建图形时使用路径压缩,结果会非常快。


我认为这是因为我试图将其合并到 用它实现克鲁斯卡尔的算法。在我找到所有之后 连接的组件,我想对表示表示的输出进行排序 每个不相交集的每个不相交集。很抱歉打扰你 但如果可能的话,你可能有任何伪代码来解释你 意味 着?

这些集已由公共根节点标识。完成所有并集后,每个唯一集将具有一个根。 因此,然后运行每个节点并在其上调用Find。 这个怎么样:

typedef std::list< Node* > TNodeList;
typedef std::map< Node*, TNodeList > TSetMap;
TSetMap mysets;
// Assuming you have nodes stored in the list type I declared above...
for( TNodeList::iterator n = nodes.begin(); n != nodes.end(); n++ )
{
Node *thisnode = *n;
Node *rootnode = Find(thisnode);
// Add to list for root.  Using the [] operator on map will create a new
// list if none exists for that node.
mysets[rootnode].push_back(thisnode);
}

现在你有一张地图,将所有集合作为单独的列表,你可以做你喜欢的事情......

std::cout << "Number of disjoint sets: " << mysets.size() << std::endl;
int count = 0;
for( TSetMap::iterator s = mysets.begin(); s != mysets.end(); s++ )
{
TNodeList & nl = s->second;
std::cout << "Set " << ++count << " contains " << nl.size() << " nodesn";
}

若要使所有这些调用Find高效,应在Union函数中实现路径压缩。

听起来好像你的图是定向的,在这种情况下,联合查找并不能真正帮助连接(如果我没记错的话,它通常用于确定 Kruskal 算法中的最小生成树,但这适用于无向图)。如果您的图形恰好是无向的,则可以使用联合查找来确定所有连接的组件,方法是在所有节点上进行两次传递:

  1. 对于每个节点并集该节点及其具有边的所有节点。
  2. 对于每个节点,找到表示的节点并检查是否已报告。如果没有,请报告并放入例如std::set<T>(因为T是用于识别代表的类型)。

实际上,使用DFS等搜索算法可能更容易:

  1. 对于每个节点,检查它是否已被访问过。
  2. 如果未访问,则它是新连接组件的一部分:在节点上启动DFS,并标记因此找到的每个节点(还可以将遇到的所有节点报告为连接组件的一部分)。

该算法的优点是它也是 O(n)(在最坏的情况下,另一个算法是 O(n log n),其中每个连接的组件仅包含一个节点)。这两种算法都没有优雅地处理有向图。