Cod sursa(job #2306012)

Utilizator flatmapLambda flatmap Data 21 decembrie 2018 14:57:16
Problema Componente tare conexe Scor 0
Compilator java Status done
Runda Arhiva educationala Marime 3.08 kb
import java.io.*;
import java.util.*;

public class Main {
    private static final String INPUT_FILE_PATH = "ctc.in";
    private static final String OUTPUT_FILE_PATH = "ctc.out";

    public static void main(String[] args) throws FileNotFoundException {
        Scanner sc = new Scanner(new FileReader(INPUT_FILE_PATH));
        int n = sc.nextInt();
        DirectedGraph graph = new DirectedGraph(n);
        int m = sc.nextInt();
        while (m-- > 0) {
            int from = sc.nextInt();
            int to = sc.nextInt();
            --from;
            --to;
            graph.addEdge(from, to);
        }
        PrintWriter pw = new PrintWriter(OUTPUT_FILE_PATH);
        List<List<Integer>> strongConnComp = graph.getStrongConnectedComponents();
        pw.println(strongConnComp.size());
        strongConnComp.forEach(comp -> {
            comp.forEach(node -> pw.print((node + 1) + " "));
            pw.println();
        });
        pw.flush();
    }

    static class DirectedGraph {
        private int n;
        private List<List<Integer>> adjMatrix;
        private List<List<Integer>> transAdjMatrix;
        private List<List<Integer>> strongConnComp;
        private boolean[] visited;
        private Stack<Integer> visitedStack;

        DirectedGraph(int n) {
            this.n = n;
            adjMatrix = new ArrayList<>();
            transAdjMatrix = new ArrayList<>();
            for (int i = 0; i < n; ++i) {
                adjMatrix.add(new ArrayList<>());
                transAdjMatrix.add(new ArrayList<>());
            }
        }

        void addEdge(int from, int to) {
            adjMatrix.get(from).add(to);
            transAdjMatrix.get(to).add(from);
        }

        List<List<Integer>> getStrongConnectedComponents() {
            strongConnComp = new ArrayList<>();
            visited = new boolean[n];
            visitedStack = new Stack<>();
            Arrays.fill(visited, false);
            for (int i = 0; i < n; ++i) {
                if (!visited[i]) {
                    dfs1(i);
                }
            }
            Arrays.fill(visited, false);
            int cnt = 0;
            while (!visitedStack.empty()) {
                int top = visitedStack.peek();
                visitedStack.pop();
                if (!visited[top]) {
                    strongConnComp.add(new ArrayList<>());
                    dfs2(top, cnt++);
                }
            }
            return strongConnComp;
        }

        private void dfs2(int i, int scIndex) {
            visited[i] = true;
            transAdjMatrix.get(i).forEach(node -> {
                if (!visited[node]) {
                    dfs2(node, scIndex);
                }
            });
            strongConnComp.get(scIndex).add(i);
        }

        private void dfs1(int i) {
            visited[i] = true;
            adjMatrix.get(i).forEach(node -> {
                if (!visited[node]) {
                    dfs1(node);
                }
            });
            visitedStack.add(i);
        }
    }
}