当前位置: 首页 > 知识库问答 >
问题:

强连通分量

慕铭
2023-03-14

import java.util.*;
import java.util.Scanner;
import java.util.ArrayList;

class StronglyConnectedComponents {
    int V;  //number of nodes
    ArrayList<Integer> adj[];   //adjacenty list
    int time;

    StronglyConnectedComponents(int v) {
        this.V = v;
        this.time = 0;
        this.adj = new ArrayList[v];
        Arrays.fill(adj, new ArrayList());  //adj list of v elements(arrayLists)

    }

    void addEdge(int v, int w) {
        adj[v].add(w);
    }

    void util(int u, int low[], int disc[], int stackMember[], Stack<Integer> st) {
        stackMember[u] = 1; //visited
        disc[u] = time;  //first time visiting time
        low[u] = time++;  //after update time +1
        st.push(u);  //dfs - take last added as first observal vertex

        for (Integer i : adj[u]) { //traversing adjacents of u
            if (disc[i] == -1) {
                util(i, low, disc, stackMember, st);
                if (low[u] > low[i]) low[u] = low[i];  //update If node v is not visited
            } else if (stackMember[i] != 0)  //if i is still in stack update value
            {
                if (low[u] > disc[i]) low[u] = disc[i];
            }
        }

        int w = -1;
        if (low[u] == disc[u]) {
            while (w != u) //while there is a path
            {

                w = (int) st.pop();
                stackMember[w] = 0;
                System.out.print(w + " ");

            }
            System.out.println();
        }


    }

    void SCC() {
        //first time all vertices has no parent, therefore fill with -1
        int disc[] = new int[V];
        Arrays.fill(disc, -1);
        int low[] = new int[V];
        Arrays.fill(low, -1);

        int stackMember[] = new int[V];
        Stack<Integer> st = new Stack<Integer>();
        //all vertices not visited filling
        for (int i = 0; i < V; i++) {
            if (disc[i] == -1)//if not visited vertex
                util(i, low, disc, stackMember, st);
        }

    }

    public static void main(String args[]) {
        Scanner sc = new Scanner(System.in);
        System.out.println("Enter the number of nodes");
        int n = sc.nextInt();
        System.out.println("Enter the number of edge");
        int m = sc.nextInt();
        m++;
        StronglyConnectedComponents g = new StronglyConnectedComponents(n);
        System.out.println("Enter the edges:");

        while (m-- > 0 && sc.hasNext()) {
            String[] input = sc.nextLine().split(" ");
            if (input.length == 2) {
                g.addEdge(Integer.parseInt(input[0]), Integer.parseInt(input[1]));
            }
        }
        g.SCC();

    }
}
Enter the number of nodes
5
Enter the number of edge
5
Enter the edges:
1 0
0 2
2 1
0 3
3 4
4 3 1 2 0 

输出应该如下所示:

0 1 2
3
4

我甚至不知道为什么会有这样的错误。我将代码从https://www.geeksforgeeks.org/tarjan-algorithm-find-strong-connected-components/改为我的代码,并添加了input机会。我问过这个问题,一个朋友说:“这是addEdge方法中添加w后的两个代码的输出,在您的代码中w添加到所有元素中,而在原始代码中只添加到图V中”,但我不知道怎么做

共有1个答案

鄢朝斑
2023-03-14

问题出在为adj数组初始化列表的那一行:

Arrays.fill(adj, new ArrayList());

当我们查看Java文档时,我们从数组中阅读了public static void fill(Object[]a,Object val)方法:

将指定的对象引用分配给指定对象数组的每个元素。

for(int i = 0; i < adj.length; i++) {
  adj[i] = new ArrayList<>();
}
 类似资料:
  • 在本章的剩余部分,我们将把注意力转向一些非常大的图。我们将用来研究一些附加算法的图,由互联网上的主机之间的连接和网页之间的链接产生的图。 我们将从网页开始。 像 Google 和 Bing 这样的搜索引擎利用了网页上的页面形成非常大的有向图。 为了将万维网变换为图,我们将把一个页面视为一个顶点,并将页面上的超链接作为将一个顶点连接到另一个顶点的边缘。 Figure 30 展示了从 Luther C

  • 如果您不知道SCC算法是如何工作的,请阅读本文:https://www.hackerearth.com/practice/algorithms/graphs/strong-connected-components/tutorial/(这是我能找到的最好的文章)。 在找到每个节点的完成时间后,将原图反转,从时间最高的节点开始运行DFS。如果我们从原始图中最小的节点开始运行DFS呢?为什么不管用?

  • 我有一个强连通图。我想移除一个边并检查是否仍然保持强连接。因为我将N=图中节点的总数取为10,并且我感兴趣的大多数图都有25条以上的边,所以很难检查一次使用一条,去掉边。 如何解决这个问题?多谢了。

  • 我在读关于BFS和DFS的图算法。当我在分析用DFS寻找图中强连通分量的算法时,我产生了一个疑问。为了寻找强连通分量,book(Coremen)首先在图上运行DFS,以得到顶点的完成时间,然后在图的转置上按照第一个DFS得到的完成时间的递减顺序运行DFS。但是我不能理解为什么第二个DFS必须按照完成时间运行。我的意思是,即使我们直接在图的转置上运行DFS(忽略完成时间),它也会给我们连接的组件吗?

  • 我想在无向图中找到一个强连通分量,即如果我从一个节点开始,那么我将回到节点,并且每个边都被精确地访问一次。 对于有向图,可以用Tarjan算法求强连通分量,但是对于无向图,该怎么办。

  • 我正在努力自学图论,现在试图理解如何在图中找到SCC。我读过关于SO的几个不同的问题/答案(例如,1、2、3、4、5、6、7、8),但我找不到一个可以遵循的完整的一步一步的例子。 根据CORMEN(算法导论),一种方法是: 调用DFS(G)计算每个顶点u的完成时间f[u] 计算转置(G) 调用DFS(转置(G)),但在DFS的主循环中,按F[u]递减的顺序考虑顶点(如步骤1中计算的那样) 输出步骤