【问题标题】:DFS on reversed graph反向图上的 DFS
【发布时间】:2015-03-26 18:08:12
【问题描述】:

我必须在图形上使用 DFS,然后在反向图形上使用,并且图形是有向的。我很好奇,不是首先将邻接列表反转为另一个邻接列表,然后将其复制回原始邻接列表,然后再次调用 DFS,有什么方法可以让我知道我必须使用邻接来编写 DFS 函数以相反的方式列出。以下是我的 Java 代码,我用它来判断我的图是否是强连接的。我会非常有帮助的。简而言之,我想避免 rev_graph 函数并最小化我的代码。

    import java.util.*;
    class Strongly_conn
    {
     static ArrayList<LinkedList<Integer>> g;
     static ArrayList<LinkedList<Integer>> g1;
     static int []visited;
     public static void create_graph()
     {
      int n,i,k,j;
      Scanner s=new Scanner(System.in);
      System.out.println("enter the value of number of vertices");
      n=s.nextInt();
      visited=new int[n];
      for(i=0;i<n;++i)
       visited[i]=0;
      g=new ArrayList<LinkedList<Integer>>();
      for(i=0;i<n;++i)
      {
       g.add(new LinkedList<Integer>());
       System.out.println("enter the number of vertices adjacent to "+ (i+1)+" and what are they?" );         
       k=s.nextInt();
       for(j=1;j<=k;++j)
       g.get(i).add(s.nextInt());
      }      
     }
     public static void main(String []args)
     {
      int so,i;      
      Scanner s=new Scanner(System.in);
      create_graph();
      System.out.println("enter any vertex");
      so=s.nextInt();
      DFS(so);
      for(i=0;i<g.size();++i)
       if(visited[i]==1)
       continue;
       else {System.out.println("the directed graph is not strongly connected");System.exit(0);}
      for(i=0;i<g.size();++i)
       visited[i]=0;
      rev_graph(); 
      DFS(so);
      for(i=0;i<g.size();++i)
       if(visited[i]==1)
        continue;
       else {System.out.println("the directed graph is not strongly connected");System.exit(0);}
      System.out.println("the directed graph is strongly connected"); 
     }
      public static void DFS(int s)
      {
       visited[s-1]=1;     
       for(int e:g.get(s-1))
        if(visited[e-1]==0)
       DFS(e);
       else continue;
      }
      public static void rev_graph()
      {
       int i;
       g1=new ArrayList<LinkedList<Integer>>();
       for(i=0;i<g.size();++i)
        g1.add(new LinkedList<Integer>());
       for(i=0;i<g.size();++i)
       for(int e:g.get(i))
        g1.get(e-1).add(i+1);
       g=new ArrayList<LinkedList<Integer>>(g1);
      }       
     }

【问题讨论】:

    标签: java graph depth-first-search


    【解决方案1】:

    想法是当你在访问一个节点时遍历图,将访问的节点放入堆栈,将所有节点放入堆栈,然后在反向遍历方法弹出堆栈中,你将获得同一个图的逆序遍历。这很可能会起作用。

    【讨论】:

      【解决方案2】:

      这里的基本思想不是遍历所有集合节点子节点,而是遍历其父节点。假设您有一个邻接矩阵(正如您所指出的那样),而不是查找特定行的所有设置的列,而是查看为该节点设置的所有行。

      例子:

      假设你有一个类似的图表

      1 -> 2
      4 -> 1
      3 -> 2
      4 -> 3
      

      所以你的矩阵是:

      [0 1 0 0]
      [0 0 0 0]
      [0 1 0 0]
      [1 0 1 0]
      

      所以在这里,您可以看到节点1 有一个子节点2(从第一行开始)。但是,如果您查看列(第二列)213 的子级。因此,您可以将13 添加到您的堆栈并继续。

      【讨论】:

      • 我特别提到了邻接表
      • 所以?有什么不同?
      • 首先,我讨厌你的态度。当一个陌生人试图帮助你时,这不是一个人的反应。其次,如果你不明白这一点,我认为你需要回到学习基础。
      • “基础”说邻接列表比邻接矩阵有更好的空间复杂度,这是我的主要目标。
      • 科长,绝对没有区别。您需要做的就是将这些列表及其子列表映射到哈希表中,并应用上述相同的算法。键是节点头,值是子节点。事实上,这比矩阵更容易。 PS:您的帖子上有一个 java 标签,但仍未收到任何回复。这是有原因的。尽量保持谦虚,这总是好的。
      猜你喜欢
      • 2013-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多