Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
137 changes: 137 additions & 0 deletions jugwang/week7/BOJ11724.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/*
연결 요소의 개수 (백준 11724번)

- 시간 복잡도: O(V + E)
- V: 정점의 개수, E: 간선의 개수
- 모든 정점을 한 번씩 방문하고, 각 정점에서 인접한 정점들을 탐색
- BFS를 통해 연결된 모든 정점을 방문하므로 O(V + E)
- 전체적으로 모든 정점과 간선을 한 번씩만 처리

- 풀이
1. 무방향 그래프에서 연결 요소(Connected Component)의 개수를 구하는 문제
2. 연결 요소란 서로 연결된 정점들의 집합으로, 다른 연결 요소와는 경로가 없음
3. BFS 또는 DFS를 사용하여 각 연결 요소를 탐색
4. 방문하지 않은 정점에서 BFS를 시작할 때마다 하나의 연결 요소를 발견
5. 모든 정점을 확인하여 총 연결 요소의 개수를 계산

- 의사코드
```
solution(graph, nodeCount):
count = 0

for i = 1 to nodeCount:
if not visited[i]:
BFS(i, graph) // 새로운 연결 요소 발견
count++

return count

BFS(startNode, graph):
queue = new Queue()
queue.add(startNode)
visited[startNode] = true

while queue is not empty:
currentNode = queue.poll()

for each neighbor in graph[currentNode]:
if not visited[neighbor]:
visited[neighbor] = true
queue.add(neighbor)
```

*/

import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Queue;

class Solution {
boolean[] visited;

public Solution(int node) {
this.visited = new boolean[node+1];
}

public int solution(ArrayList<ArrayList<Integer>> graph, int node) {
int count = 0;

for(int i=1; i<=node; i++) {
if(!visited[i]) {
visited[i] = true;
bfs(i, graph);
count++;
}
}
return count;
}

public void bfs(int startNode, ArrayList<ArrayList<Integer>> graph) {
Queue<Integer> q = new ArrayDeque<>();

q.add(startNode);
visited[startNode] = true;

while(!q.isEmpty()){
int currentNode = q.poll();

visited[currentNode] = true;

for (int neighbor : graph.get(currentNode)) {
if (!visited[neighbor]) {
visited[neighbor] = true;
q.add(neighbor);
}
}
}
}
}

public class BOJ11724 {
public static void main(String[] args) {
// Test cases
int[] vertices = {6, 6};
int[] edgeCounts = {5, 8};
int[][][] edges = {
{{1, 2}, {2, 5}, {5, 1}, {3, 4}, {4, 6}},
{{1, 2}, {2, 5}, {5, 1}, {3, 4}, {4, 6}, {5, 4}, {2, 4}, {2, 3}}
};
int[] expectedResults = {2, 1};

for (int t = 0; t < vertices.length; t++) {
System.out.println("--- Test Case " + (t + 1) + " ---");

int vertex = vertices[t];
int edgeCount = edgeCounts[t];

System.out.println("Vertices: " + vertex + ", Edges: " + edgeCount);
System.out.println("Edge connections:");
for (int[] edge : edges[t]) {
System.out.println(" " + edge[0] + " - " + edge[1]);
}

ArrayList<ArrayList<Integer>> graph = new ArrayList<>();
for (int i = 0; i <= vertex; i++) {
graph.add(new ArrayList<>());
}

// 간선 정보 설정 (무방향 그래프)
for (int[] edge : edges[t]) {
int node1 = edge[0];
int node2 = edge[1];
graph.get(node1).add(node2);
graph.get(node2).add(node1);
}

Solution solved = new Solution(vertex);
int result = solved.solution(graph, vertex);

System.out.println("Result: " + result + " connected components");
System.out.println("Expected: " + expectedResults[t] + " connected components");

boolean isSuccess = (result == expectedResults[t]);
System.out.println(isSuccess ? ">>> SUCCESS" : ">>> FAILURE");
System.out.println();
}
}
}
178 changes: 178 additions & 0 deletions jugwang/week7/BOJ15591.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
/*
MooTube (Silver) (백준 15591번)

- 시간 복잡도: O(Q × N)
- Q: 쿼리 개수, N: 노드 개수
- 각 쿼리마다 BFS로 트리 전체 탐색하므로 O(N)
- 전체 시간 복잡도는 O(Q × N)

- 풀이
1. 트리에서 두 동영상 간의 경로상 가장 작은 가중치가 USADO 값
2. 시작 노드에서 BFS로 모든 연결된 노드 탐색
3. 경로상 최소 가중치가 k 이상인 노드들의 개수 계산
4. 각 쿼리마다 독립적으로 BFS 수행하여 조건을 만족하는 노드 개수 반환

- 슈도코드
```
solution(questionNum, questions, nodeNum):
for each question:
distance = question[0] // 최소 USADO 값
start = question[1] // 시작 노드
result = BFS(distance, start, nodeNum)
return results

BFS(distance, start, nodeNum):
count = 0
visited[nodeNum+1] = false로 초기화
queue = new Queue()

queue.add([start, MAX_VALUE])
visited[start] = true

while queue is not empty:
current = queue.poll()
currentNode = current[0]
currentDistance = current[1]

for each neighbor in adjacentList[currentNode]:
if not visited[neighbor.to]:
visited[neighbor.to] = true
newDistance = min(currentDistance, neighbor.weight)
if newDistance >= distance:
queue.add([neighbor.to, newDistance])
count++

return count
```

*/

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;

class Node {
int to;
int weight;

public Node(int to, int weight) {
this.to = to;
this.weight = weight;
}
}

class Solution {
ArrayList<ArrayList<Node>> link;

public Solution(int nodeNum) {
this.link = new ArrayList<>();
for(int i=0; i<=nodeNum; i++) {
link.add(new ArrayList<>());
}
}

public int[] solution(int questionNum, int[][] questions, int nodeNum) {
int[] response = new int[questionNum];

for (int i=0; i<questionNum; i++) {
int distance = questions[i][0];
int start = questions[i][1];

response[i] = bfs(distance, start, nodeNum);
}

return response;
}

public int bfs(int distance ,int start, int nodeNum) {
int count = 0;
boolean[] visited = new boolean[nodeNum+1];
Queue<int[]> q = new LinkedList<>();

q.add(new int[]{start,Integer.MAX_VALUE});
visited[start] = true;

while (!q.isEmpty()) {
int[] poll = q.poll();

int currentNode = poll[0];
int currentDistance = poll[1];

for (Node nextNode : link.get(currentNode)) {
if(!visited[nextNode.to]) {
visited[nextNode.to] = true;
int newDistance = Math.min(currentDistance, nextNode.weight);
if (newDistance >= distance) {
q.add(new int[]{nextNode.to, newDistance});
count++;
}
}
}
}

return count;
}
}


public class BOJ15591 {
public static void main(String[] args) {
// Test cases
int[] nodeNums = {4};
int[] questionNums = {3};
int[][][] edges = {
{{1, 2, 3}, {2, 3, 2}, {2, 4, 4}}
};
int[][][] questions = {
{{1, 2}, {4, 1}, {3, 1}}
};
int[][] expectedResults = {
{3, 0, 2}
};

for (int t = 0; t < nodeNums.length; t++) {
System.out.println("--- Test Case " + (t + 1) + " ---");

int nodeNum = nodeNums[t];
int questionNum = questionNums[t];

System.out.println("Nodes: " + nodeNum + ", Questions: " + questionNum);
System.out.println("Edges:");
for (int[] edge : edges[t]) {
System.out.println(" " + edge[0] + " - " + edge[1] + " (weight: " + edge[2] + ")");
}
System.out.println("Questions:");
for (int[] question : questions[t]) {
System.out.println(" k=" + question[0] + ", start=" + question[1]);
}

Solution solved = new Solution(nodeNum);

// 간선 추가
for (int[] edge : edges[t]) {
solved.link.get(edge[0]).add(new Node(edge[1], edge[2]));
solved.link.get(edge[1]).add(new Node(edge[0], edge[2]));
}

int[] results = solved.solution(questionNum, questions[t], nodeNum);

System.out.print("Results: ");
for (int i = 0; i < results.length; i++) {
System.out.print(results[i]);
if (i < results.length - 1) System.out.print(", ");
}
System.out.println();

System.out.print("Expected: ");
for (int i = 0; i < expectedResults[t].length; i++) {
System.out.print(expectedResults[t][i]);
if (i < expectedResults[t].length - 1) System.out.print(", ");
}
System.out.println();

boolean isSuccess = java.util.Arrays.equals(results, expectedResults[t]);
System.out.println(isSuccess ? ">>> SUCCESS" : ">>> FAILURE");
System.out.println();
}
}
}
Loading