在协调图中,识别不属于任何循环的集线器对于不同的应用程序至关重要。这些中心构建了非循环子图的基础,并在理解一般图表结构方面发挥着重要作用。通过使用有效的图表交叉计算,例如 Profundity First Hunt (DFS) 或 Tarjan 对紧密关联部件的计算,我们可以毫不费力地决定并打印不参与任何循环的集线器。这些方法保证了没有循环合作的中心的特色,为图表的非循环部分提供了重要的知识,并支持与图表相关的不同批判性思维情况。
使用的方法
-
带循环检测的深度优先搜索 (DFS)
-
Tarjan 的强连通分量算法
带循环检测的深度优先搜索 (DFS)
在此方法中,我们使用深度优先追踪 (DFS) 来导航协调图表并区分途中的周期。我们标记访问过的中心并保留一份清单,以便以持续的 DFS 方式跟踪中心。如果我们遇到后沿(以持续的 DFS 方式到达集线器的边缘),我们会区分一个周期。在 DFS 结束时,正在进行的 DFS 方式中的中心对于一个周期将很重要。不采用持续 DFS 方式的集线器不属于任何循环,可以打印。
算法
-
在图表上从每个未访问过的中心开始进行深度首次狩猎 (DFS)。
-
在 DFS 期间,标记访问过的集线器并将其添加到正在进行的 DFS 路径列表中。
-
如果我们遇到后沿(当前 DFS 方式中到集线器的边缘),我们会区分一个周期,并将当前 DFS 方式中的所有集线器标记为周期的一部分。
-
当集线器的 DFS 完成后,将其从正在进行的 DFS 路径列表中删除。
-
完成所有轮毂的 DFS 后,不属于任何循环的轮毂将保持不变,我们可以打印它们。
示例
#include
#include
class Graph {
public:
Graph(int numVertices);
void addEdge(int src, int dest);
void DFS();
private:
void DFSUtil(int v, std::vector& visited, std::vector& dfsPath);
int numVertices;
std::vector adjList;
};
Graph::Graph(int numVertices) : numVertices(numVertices) {
adjList.resize(numVertices);
}
void Graph::addEdge(int src, int dest) {
adjList[src].push_back(dest);
}
void Graph::DFSUtil(int v, std::vector& visited, std::vector& dfsPath) {
visited[v] = true;
dfsPath.push_back(v);
for (int neighbor : adjList[v]) {
if (!visited[neighbor]) {
DFSUtil(neighbor, visited, dfsPath);
}
else {
std::cout