【问题标题】:detect cycle in directed graph with non-recursive dfs使用非递归 dfs 检测有向图中的循环
【发布时间】:2019-05-26 19:15:08
【问题描述】:

我的代码可以正常工作,但不适用于所有测试用例。

我在这里要做的是创建一个“布尔 ifparent 数组”,它保存我正在遍历的路径的记录。

“布尔访问数组”记录所有访问过的顶点。

我正在为 DFS 使用堆栈。

//v is no of vertex, adj[] is the adjacency matrix
bool isCyclic(int v, vector<int> adj[])
{
    stack<int> st;
    st.push(0);

    vector<bool> visited(v, false);
    vector<bool> ifparent(v, false);
    int flag= 0;

    int s;
    while(!st.empty()){
        s= st.top();
        ifparent[s]= true;
        visited[s]=true;
        flag=0;

        for(auto i: adj[s]){
            if(visited[i]){
                if(ifparent[i])
                    return true;
            }
            else if(!flag){
                st.push(i);
                flag= 1;
            }
        }

        if(!flag){
            ifparent[s]= false;
            st.pop();
        }
    }

    return false;

}

【问题讨论】:

  • 哪些情况不起作用?对于这些情况,实际结果是什么,预期结果是什么?
  • @JaMiT link 这是问题的链接。
  • 问题应该是独立的,不依赖外部链接获取关键信息。请编辑问题以说明哪些情况不起作用,这些情况下的实际结果是什么,以及这些情况下的预期结果是什么。

标签: c++ algorithm graph-theory depth-first-search


【解决方案1】:

如果您喜欢使用 DFS 进行循环检测的迭代方法,我将向您推荐您的代码的一些重新组织版本,其中我以更常见的方式编写 DFS。

bool isCyclic(int V, vector<int> adj[]) {
  vector<bool> visited (V, false);
  vector<bool> on_stack (V, false);
  stack<int> st;

  for (int w = 0; w < V; w++) {

    if (visited[w])
      continue;
    st.push(w);

    while (!st.empty()) {
      int s = st.top();

      if (!visited[s]) {
        visited[s] = true;
        on_stack[s] = true;
      } else {
        on_stack[s] = false;
        st.pop();
      }

      for (const auto &v : adj[s]) {
        if (!visited[v]) {
          st.push(v);
        } else if (on_stack[v]) {
          return true;
        }
      }
    }
  }
  return false;
}

【讨论】:

  • if (!visited[v]) { no_unseen_adjacent = false; st.push(五);此块将推送堆栈中的每个相邻节点,它不再是 DFS。
  • 推送所有相邻节点不会破坏 dfs 遍历。它只是关于节点访问的顺序。事实上递归和迭代方法有different order。无论如何,我的代码中有一个错误,我已修复它并检查了您提供的link 上的新代码。现在测试系统接受它。
  • 您的代码很有帮助。我发现我没有考虑断开图的情况。
  • 也考虑循环检测算法的递归版本。我认为它更直观。这是link,实现良好。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-03-12
  • 1970-01-01
  • 1970-01-01
  • 2015-02-25
  • 2016-01-27
  • 2018-08-19
  • 2020-02-10
相关资源
最近更新 更多