Algoritmo para hallar componentes fuertemente conexas(SCC) en grafos dirigidos.
SE DEBEN LIMPIAR LAS ESTRUCTURAS DE DATOS ANTES DE UTILIZARSE

   static int v;
    static int n = 5000; // Máxima cantidad de nodos
    static int dfs_low[] = new int[n];
    static int dfs_num[] = new int[n];
    static boolean marked[] = new boolean[n];
    static Stack<Integer> s;
    static int dfsCont, cantSCC;
    static ArrayList<Integer> ady[] = new ArrayList[n];

    public static void tarjanSCC(int u) {
        dfs_low[u] = dfs_num[u] = dfsCont;
        dfsCont++;
        s.push(u);
        marked[u] = true;
        int j, v;
        for (j = 0; j < ady[u].size(); j++) {
            v = ady[u].get(j);

            if (dfs_num[v] == -1) {
                tarjanSCC(v);
            }

            if (marked[v]) {
                dfs_low[u] = Math.min(dfs_low[u], dfs_low[v]);
            }
        }

        if (dfs_low[u] == dfs_num[u]) {
            cantSCC++;
            /* Esta seccion comentada se usa para imprimir las componentes conexas */
		/* System.out.println("COMPONENTE CONEXA #" + cantSCC );
		while( !s.empty() ){
			v = s.peek();
			s.pop();
			marked[v] = false;
			System.out.println(v);
			if( u == v ) break;
		} */
        }
    }

    public static void main(String[] args) {

        for (int i = 0; i < n; i++) { //inicializa las estructuras necesarias para la ejecucion del algoritmo.
            ady[i] = new ArrayList<Integer>();
            dfs_low[i] = 0;
            dfs_num[i] = -1;
            marked[i] = false;
        }

        for (int i = 0; i < v; i++) { //Por si el grafo no es conexo
            if (dfs_num[i] == -1) {
                dfsCont = 0;
                s = new Stack<Integer>();
                tarjanSCC(i);
            }
        }
    }




Algoritmo para hallar componentes fuertemente conexas(SCC) en grafos dirigidos.
SE DEBEN LIMPIAR LAS ESTRUCTURAS DE DATOS ANTES DE UTILIZARSE

   static int v;
    static int n = 5000; // Máxima cantidad de nodos
    static int dfs_low[] = new int[n];
    static int dfs_num[] = new int[n];
    static boolean marked[] = new boolean[n];
    static Stack<Integer> s;
    static int dfsCont, cantSCC;
    static ArrayList<Integer> ady[] = new ArrayList[n];

    public static void tarjanSCC(int u) {
        dfs_low[u] = dfs_num[u] = dfsCont;
        dfsCont++;
        s.push(u);
        marked[u] = true;
        int j, v;
        for (j = 0; j < ady[u].size(); j++) {
            v = ady[u].get(j);

            if (dfs_num[v] == -1) {
                tarjanSCC(v);
            }

            if (marked[v]) {
                dfs_low[u] = Math.min(dfs_low[u], dfs_low[v]);
            }
        }

        if (dfs_low[u] == dfs_num[u]) {
            cantSCC++;
            /* Esta seccion comentada se usa para imprimir las componentes conexas */
		/* System.out.println("COMPONENTE CONEXA #" + cantSCC );
		while( !s.empty() ){
			v = s.peek();
			s.pop();
			marked[v] = false;
			System.out.println(v);
			if( u == v ) break;
		} */
        }
    }

    public static void main(String[] args) {
	    
	cantSCC=0;
        for (int i = 0; i < n; i++) { //inicializa las estructuras necesarias para la ejecucion del algoritmo.
            ady[i] = new ArrayList<Integer>();
            dfs_low[i] = 0;
            dfs_num[i] = -1;
            marked[i] = false;
        }

        for (int i = 0; i < v; i++) { //Por si el grafo no es conexo
            if (dfs_num[i] == -1) {
                dfsCont = 0;
                s = new Stack<Integer>();
                tarjanSCC(i);
            }
        }
    }




Update Tarjan.java