728x90
문제 제시
- 보통 이런 문제에서 간선의 수는 도로의 갯수, 도로 1개당 이동시간 몇 분 이런식으로 나온다
- 1번 도시에서 각 도시까지 가는 최소 이동 시간을 구하시오
- 1번 도시에서 3번, 4번 도시까지 최소 이동 시간은 1분
- 첫째 줄에는 도시의 수 N(1≤N<20) 와 도로 M 의 갯수가 주어진다. 그 후 M 번에 걸쳐 연결 정보가 주어진다.
- 1번 도시에서는 3번과 4번 도시로 밖에 가지 못한다
BFS 로 접근하기
- 문제의 기본 접근법은 이전에 공부했던 인접 리스트 방식이다.
- ArrayList 로 n번에서 이동할 수 있는 번호를 넣어둔 후 추가로 n번에서 m 까지 이동하는데 걸리는 거리 dis 배열을 만들어서 거리를 계산한다.
- 예를들어 1번에서 이동 할 수 있는 번호는 3, 4 번이다. 또한 3, 4 번까지 거리는 1 임으로 dis[3] = 1 && dis[4] = 1 이 된다. dis[6] = 2 가 된다
- 즉 v - nv 로 이어지는 그래프에 대해서, dis[nv] = dis[v] +1 이 된다.
package BFS;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;
public class BFS_dis {
static int n, m;
static ArrayList<ArrayList<Integer>> graph;
// 해당 도시를 지났는지(탐색했는지) 체크하기 위한 체크배열
// 해당 도시를 지났다면 ch 배열에 1이 들어감
static int[] ch;
// 1번 도시로부터 n 번 도시까지 거리를 저장하기 위한 dis 배열
static int[] dis;
// v 는 도시의 번호
public void dis(int v){
// Queue 생성 -> 해당 queue 는 LinkedList 를 담음
// Linklist 인 이유는 도시와 도시가 연결 linked 되어 있기 때문!!
Queue<Integer> queue = new LinkedList<Integer>();
// v 번째를 지났다면 ch 배열의 v 번째 인덱스에 1 이 들어감
ch[v] = 1;
// v 번째에서 v 번째 까지 거리는 당연 0 -> 자기 자신으로의 거리
dis[v] = 0;
// queue 에 v 를 넣기
queue.add(v);
// queue 가 비어있지 않다면 ->
while(!queue.isEmpty()){
// currentValue 는 현재 지점(도시) 로 queue 에 저장된 값을 하나 꺼내옴
int cv = queue.poll();
System.out.println("cv : "+cv);
// graph 는 Integer 를 담은 ArrayList 를 저장한 ArrayList 로
// graph.get(1) 이면 graph 의 인덱스 1번에 저장된 ArrayList 를 불러옴
for(int nv : graph.get(cv)){
if(ch[nv]==0){
System.out.println("nv : "+nv);
// nv 에 방문했으면 1 로 체크
ch[nv] = 1;
// queue 에 nv 를 넣기기
queue.offer(nv);
// nv 로의 거리는 바로 이전 값 cv까지 거리에서 +1
dis[nv] = dis[cv] +1;
}
}
}
}
public static void main(String[] args) {
BFS_dis bfs = new BFS_dis();
Scanner scan = new Scanner(System.in);
n = scan.nextInt(); // 도시의 갯수
m = scan.nextInt(); // 도로의 갯수
// 인접 리스트 생성 => Integer 를 담은 리스트를 담은 리스트
graph = new ArrayList<ArrayList<Integer>>();
for(int i=0; i<=n; i++){
graph.add(new ArrayList<Integer>());
}
ch = new int[n+1];
dis = new int[n+1];
for(int i=0; i<m; i++){
int a = scan.nextInt();
int b = scan.nextInt();
graph.get(a).add(b);
}
// 1 번 도시부터 시작
bfs.dis(1);
for(int i=2; i<=n; i++){
System.out.println(i+ " : "+dis[i]);
}
}
}
결과 확인
- 녹색은 내가 넣은 도시의 번호와 연결된 도로이다.
- cv 는 현재 방문한 도시의 번호, nv 는 cv 와 연결되어 있으며, 다음 방문한 도시의 번호이다.
- 1번부터 시작한다고 했을 때 1번에서 3, 4 번 도시를 방문한다.
- 3번 도시는 4번 도시외 연결된 도시가 없고, 4번 도시는 이미 1번 도시를 통해서 방문 했음으로 다음 방문할 도시가 없기 때문에 종료된다 ⇒ 거리 1
- 1번에서 4번 도시까지의 거리는 1이고, 4번 도시에서 방문할 수 있는 도시는 5, 6번이다. 이때 5, 6번까지으 거리는 4번까지의 거리 +1 이다 ⇒ dis[5] = dis[4] + 1, dis[6] = dis[4] + 1
- 5번 도시 역시 3번과 마찬가지로 4번을 통해서 방문했고, 연결된 도시가 없음으로 종료된다 ⇒ 거리 2
- 6번 도시까지의 거리도 2
- 2번 도시는 6번에서만 방문할 수 있고, 따라서 6번까지의 거리 +1 이 된다 ⇒ dis[2] = dis[6] +1
- 거리는 3
'Java - 알고리즘' 카테고리의 다른 글
DFS 문제풀이 : 중복순열 다루기, 거스름돈 계산하기 (0) | 2022.06.19 |
---|---|
DFS 문제풀이 : 바둑이 승차, 잔돈 계산하기 (0) | 2022.06.19 |
알고리즘 - 버블 정렬, 삽입 정렬 (0) | 2022.02.25 |
그래프와 인접 행렬 & 인접 리스트 (0) | 2021.12.01 |
자바 알고리즘 - 큐(Queue), BFS(너비 우선 탐색), 최단 횟수 찾기 (0) | 2021.11.11 |
댓글