메모리: 24380 KB, 시간: 284 ms
그래프 이론, 그래프 탐색, 너비 우선 탐색, 깊이 우선 탐색
2024년 8월 8일 00:39:10
그래프를 DFS로 탐색한 결과와 BFS로 탐색한 결과를 출력하는 프로그램을 작성하시오. 단, 방문할 수 있는 정점이 여러 개인 경우에는 정점 번호가 작은 것을 먼저 방문하고, 더 이상 방문할 수 있는 점이 없는 경우 종료한다. 정점 번호는 1번부터 N번까지이다.
첫째 줄에 정점의 개수 N(1 ≤ N ≤ 1,000), 간선의 개수 M(1 ≤ M ≤ 10,000), 탐색을 시작할 정점의 번호 V가 주어진다. 다음 M개의 줄에는 간선이 연결하는 두 정점의 번호가 주어진다. 어떤 두 정점 사이에 여러 개의 간선이 있을 수 있다. 입력으로 주어지는 간선은 양방향이다.
첫째 줄에 DFS를 수행한 결과를, 그 다음 줄에는 BFS를 수행한 결과를 출력한다. V부터 방문된 점을 순서대로 출력하면 된다.
풀이
기본적인 dfs와 bfs를 실행하고 그대로 출력을 하는 문제다.
다만 인접 노드 중 노드의 숫자가 작은 것 먼저 방문을 하라는 조건에서 막히는 사람이 많을 것 같다.
노드의 숫자가 작은 것 또는 큰 것 먼저 방문을 시키는 것은 간선의 정보를 따로 배열로 만들어서 받아두면 간단하게 해결할 수 있다.
예제 입력 1
4 5 1
1 2
1 3
1 4
2 4
3 4
예제 출력 1
1 2 4 3
1 2 3 4
1 | 2 | 3 | 4 | |
1 | 1 | 1 | 1 | |
2 | 1 | 1 | ||
3 | 1 | 1 | ||
4 | 1 | 1 | 1 |
위의 예제 같은 경우 다음과 같이 간선 배열을 만들 수 있는데
위와 같이 간선 배열을 따로 만들면 작은 것부터 탐색 큰 것 부터 탐색 자유롭게 가능하다.
전체 코드
public class Main {
static int N,M,V,edge[][];
static boolean visited[];
static BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
public static void main(String args[])throws IOException{
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
V = Integer.parseInt(st.nextToken());
edge = new int[N+1][N+1];
visited = new boolean[N+1];
for(int i = 0 ;i<M;i++) {
st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
edge[a][b] = 1;
edge[b][a] = 1;
}
bw.write(String.valueOf(V));
visited[V] = true;
dfs(V);
bw.write("\n");
bw.flush();
visited = new boolean[N+1];
visited[V] = true;
List<Integer> n = new ArrayList<>();
bw.write(String.valueOf(V));
n.add(V);
bfs(n);
bw.flush();
}
public static void dfs(int ob) throws IOException {
for(int i = 1 ;i<=N;i++){
if(edge[ob][i] == 1 && !visited[i]){
visited[i] = true;
bw.write(" " + i);
dfs(i);
}
}
}
public static void bfs(List<Integer> next) throws IOException {
List<Integer> n = new ArrayList<>();
while(!next.isEmpty()){
for(int i =1 ;i<=N;i++){
if(edge[next.get(0)][i] == 1 && !visited[i]){
visited[i] = true;
bw.write(" " + i);
n.add(i);
}
}
next.remove(0);
}
if(!n.isEmpty()) {
bfs(n);
}
}
}
'백준' 카테고리의 다른 글
백준 11724번 연결 요소의 개수 (java) (0) | 2024.08.09 |
---|---|
백준 1012번 유기농 배추 (java) (0) | 2024.08.08 |
백준 16956번 늑대와 양 (java) (0) | 2024.08.06 |
백준 10451번 순열 사이클 (java) (0) | 2024.08.05 |
백준 2664번 촌수계산 (java) (0) | 2024.08.05 |