From 9a3bf51d230402d6d6fb752a59ad5ac847ac7cf9 Mon Sep 17 00:00:00 2001 From: DIANNA CADEN <44316764+Me-in-U@users.noreply.github.com> Date: Thu, 23 May 2024 01:56:53 +0900 Subject: [PATCH] 2024-05-18 --- BOJ-ios/README.md | 5 +- .../Main.java" | 92 +++++++++++++++++++ 2 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 "BOJ-ios/SCC/P2150\353\262\210_Strongly_Connected_Component/Main.java" diff --git a/BOJ-ios/README.md b/BOJ-ios/README.md index 78c2298..ad3702e 100644 --- a/BOJ-ios/README.md +++ b/BOJ-ios/README.md @@ -6,5 +6,6 @@ | 2차시 | 2024.03.22 | 라빈카프 | [반복 부분문자열](https://www.acmicpc.net/problem/1605) [가장 긴 문자열](https://www.acmicpc.net/problem/3033) | [#8](https://github.com/AlgoLeadMe/AlgoLeadMe-9/pulls/8) | | 3차시 | 2024.03.26 | 펜윅트리 | [구간 합 구하기](https://www.acmicpc.net/problem/2042) | [#13](https://github.com/AlgoLeadMe/AlgoLeadMe-9/pulls/13) | | 4차시 | 2024.03.30 | 볼록껍질 | [볼록 껍질](https://www.acmicpc.net/problem/1708) | [#14](https://github.com/AlgoLeadMe/AlgoLeadMe-9/pulls/14) | -| 5차시 | 2025.04.29 | 스위핑 | [여러 직사각형의 전체 면적 구하기](https://www.acmicpc.net/problem/2672) | [#19](https://github.com/AlgoLeadMe/AlgoLeadMe-9/pulls/19) | -| 6차시 | 2025.05.13 | 위상정렬 | [줄 세우기](https://www.acmicpc.net/problem/2252) | [#20](https://github.com/AlgoLeadMe/AlgoLeadMe-9/pulls/20) | \ No newline at end of file +| 5차시 | 2024.04.29 | 스위핑 | [여러 직사각형의 전체 면적 구하기](https://www.acmicpc.net/problem/2672) | [#19](https://github.com/AlgoLeadMe/AlgoLeadMe-9/pulls/19) | +| 6차시 | 2024.05.13 | 위상정렬 | [줄 세우기](https://www.acmicpc.net/problem/2252) | [#20](https://github.com/AlgoLeadMe/AlgoLeadMe-9/pulls/20) | +| 7차시 | 2024.05.18 | SCC | [Strongly Connected Component](https://www.acmicpc.net/problem/2150) | [#22](https://github.com/AlgoLeadMe/AlgoLeadMe-9/pulls/22) | diff --git "a/BOJ-ios/SCC/P2150\353\262\210_Strongly_Connected_Component/Main.java" "b/BOJ-ios/SCC/P2150\353\262\210_Strongly_Connected_Component/Main.java" new file mode 100644 index 0000000..73dd354 --- /dev/null +++ "b/BOJ-ios/SCC/P2150\353\262\210_Strongly_Connected_Component/Main.java" @@ -0,0 +1,92 @@ +package Platinum_V.P2150번_Strongly_Connected_Component; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayDeque; +import java.util.ArrayList; +import java.util.Deque; +import java.util.StringTokenizer; +import java.util.TreeMap; + +public class Main { + protected static ArrayList[] graph; + protected static ArrayList[] reversedGraph; + protected static ArrayList[] sccGraph; + protected static Deque stack; + protected static boolean[] visited; + + @SuppressWarnings("unchecked") + public static void main(String[] args) throws IOException { + BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); + StringBuilder sb = new StringBuilder(); + + // 입력 및 초기화 + StringTokenizer st = new StringTokenizer(br.readLine()); + int V = Integer.parseInt(st.nextToken()); + int E = Integer.parseInt(st.nextToken()); + graph = new ArrayList[V + 1]; + reversedGraph = new ArrayList[V + 1]; + sccGraph = new ArrayList[V + 1]; + stack = new ArrayDeque<>(); + visited = new boolean[V + 1]; + for (int i = 1; i <= V; i++) { + graph[i] = new ArrayList<>(); + reversedGraph[i] = new ArrayList<>(); + sccGraph[i] = new ArrayList<>(); + } + for (int i = 0; i < E; i++) { + st = new StringTokenizer(br.readLine()); + int v1 = Integer.parseInt(st.nextToken()); + int v2 = Integer.parseInt(st.nextToken()); + graph[v1].add(v2); + reversedGraph[v2].add(v1); + } + + // 정상 그래프에서 DFS + for (int i = 1; i <= V; i++) + if (!visited[i]) + DFS(i); + + // 역방향 그래프에서 DFS + visited = new boolean[V + 1]; + int sccCount = 0; + while (!stack.isEmpty()) { + int vertex = stack.pop(); + if (!visited[vertex]) { + reverseDFS(vertex, ++sccCount); + } + } + sb.append(sccCount).append('\n'); + + // 정렬 + TreeMap> map = new TreeMap<>(); + for (int i = 1; i <= sccCount; i++) { + sccGraph[i].sort((o1, o2) -> o1 - o2); + map.put(sccGraph[i].get(0), sccGraph[i]); + } + map.entrySet().iterator().forEachRemaining(e -> { + e.getValue().forEach(v -> sb.append(v).append(' ')); + sb.append(-1).append('\n'); + }); + + // 출력 + System.out.print(sb.toString()); + } + + protected static void DFS(int currentVertex) { + visited[currentVertex] = true; + for (int nextVertex : graph[currentVertex]) + if (!visited[nextVertex]) + DFS(nextVertex); + stack.push(currentVertex); + } + + protected static void reverseDFS(int currentVertex, int sccCount) { + visited[currentVertex] = true; + for (int nextVertex : reversedGraph[currentVertex]) + if (!visited[nextVertex]) + reverseDFS(nextVertex, sccCount); + sccGraph[sccCount].add(currentVertex); + } +} \ No newline at end of file