젊은이의 블로그

BOJ 1260, 1920, 11724, 2343 본문

문제풀이

BOJ 1260, 1920, 11724, 2343

젊은사람 등장 2024. 11. 12. 12:01

1260 DFS와 BFS
1920 수 찾기
11724 연결 요소의 개수
2343 기타 레슨


1260 DFS와 BFS

그래프를 DFS로 탐색한 결과와 BFS로 탐색한 결과를 출력하는 프로그램을 작성하시오. 단, 방문할 수 있는 정점이 여러 개인 경우에는 정점 번호가 작은 것을 먼저 방문하고, 더 이상 방문할 수 있는 점이 없는 경우 종료한다. 정점 번호는 1번부터 N번까지이다.
 
첫째 줄에 정점의 개수 N(1 ≤ N ≤ 1,000), 간선의 개수 M(1 ≤ M ≤ 10,000), 탐색을 시작할 정점의 번호 V가 주어진다. 다음 M개의 줄에는 간선이 연결하는 두 정점의 번호가 주어진다. 어떤 두 정점 사이에 여러 개의 간선이 있을 수 있다. 입력으로 주어지는 간선은 양방향이다.
 
첫째 줄에 DFS를 수행한 결과를, 그 다음 줄에는 BFS를 수행한 결과를 출력한다. V부터 방문된 점을 순서대로 출력하면 된다.



DFS(Depth First Search) : Source node 에서 멀어지는 방향으로 갈 수 있을 때까지 가다가 더 이상 갈 수 없게 되면 "가장 가까운 갈림길로 돌아와서(backtracking, 최근에 처리한 --> stack이 적합)" 그곳으로부터 미탐색한 다른 방향으로 재진행
BFS(Breath First Search) : Source node로 부터 가까운 노드들을 먼저 방문함. (가까운 노드들이 먼저 방문되고 그 노드들의 인접노드가 멀리 있는 노드들의 인접노드 보다 먼저 방문되야함. 즉 먼저(first) 처리(in)된 것 부터(first) 꺼내서(out) 처리해야하므로 queue가 적합); 트리 자료구조에서 root를 source node로 한 Level-order traversal과 유사함.

#include <stdio.h>
#include <stdbool.h>
#pragma warning(disable:4996)

int visited[1001] = { 0, }; // 방문 표시 초기화 (false)
int graph[1001][1001] = { 0, }; // 그래프 초기화 (false)
int queue[1001]; 

void dfs(int v,int n) { // 깊이 우선 탐색
	visited[v] = true; //이제 방문했기 때문에 true로 바꾼다. (더이상 0이 아님)
	printf("%d ", v);
	for (int i = 1; i <= n; i++) {
		if (graph[v][i] && !visited[i]) // 그래프에 방문하지 않았고 간선 존재
			dfs(i, n);
	}
}

void bfs(int v, int n) { // 너비 우선 탐색
	/* 큐 변수 선언 */
	int front = 0;
	int rear = 1;
	int pop;

	visited[v] = true;
	printf("%d ", v);
	queue[0] = v;
	while (front < rear) { // 큐가 비어있으면 반복 종료 
		pop = queue[front++]; // dequeue 연산 (맨 앞, 가장 먼저 들어온 값을 출력한다.)
		for (int i = 1; i <= n; i++){
			if (graph[pop][i] && !visited[i]) {
				visited[i] = true;
				printf("%d ", i);
				queue[rear++] = i; // enqueue 연산
			}
		}
	}
}

int main() {
	int n,m, v;

	scanf("%d%d%d", &n, &m, &v);

	//그래프 생성
	for (int i = 0; i < m; i++) {
		int x, y;
		scanf("%d%d", &x, &y);
		graph[x][y] = 1; // 양방향 그래프
		graph[y][x] = 1;
	}
    
	//깊이 우선 탐색
	visited[v] = true;
	dfs(v,n);
	//--------------------------------------------------
	for (int i = 1; i <= n; i++) // 방문 노드 초기화
			visited[i] = false;
    //깊이 우선 탐색        
	visited[v] = true;
	printf("\n");
	bfs(v, n);
	return 0;
}
import sys
from collections import deque
input = sys.stdin.readline

# dfs 함수 정의(재귀)
def dfs(graph, v, visited):
    visited[v] = True # 방문 처리
    print(v, end=' ') # 현재 노드 출력
    for i in sorted(graph[v]): # 오름차순으로 이웃한 노드
        if not visited[i]: # 아직 방문하지 않은 노드가 있다면 방문
            dfs(graph, i, visited)

# bfs 함수 정의
def bfs(graph, start, visited):
    queue = deque([start]) # 큐에 현재 노드 삽입
    visited[start] = True # 방문 처리
    while queue: # 큐가 빌때 동안
        v = queue.popleft()
        print(v, end=' ') # 현재 노드 출력
        for i in sorted(graph[v]): # 오름차순으로 이웃한 노드
            if not visited[i]: # 아직 방문하지 않았다면
                queue.append(i) # 큐에 삽입
                visited[i] = True # 방문처리

n, m, start = map(int, input().rstrip().split()) # 정점, 간선, 시작정점

graph = [[] for j in range(n+1)] # 그려질 그래프 초기화
for k in range(m):
    a, b = map(int, input().rstrip().split()) # 이웃한 정점 연결시킴
    graph[a].append(b)
    graph[b].append(a)


visited = [False] * (n+1)
# dfs 함수 실행
dfs(graph, start, visited)

print()

visited = [False] * (n+1)
# bfs 함수 실행
bfs(graph, start, visited)
더보기

from collections import deque

# DFS 함수 정의, 깊이 우선 탐색
def dfs(v, visited, graph):
    visited[v] = True
    print(v, end=' ')
    for neighbor in graph[v]:
        if not visited[neighbor]:
            dfs(neighbor, visited, graph)

# BFS 함수 정의, 너비 우선 탐색
def bfs(start, graph):
    visited = [False] * (len(graph))
    queue = deque([start])
    visited[start] = True

    while queue:
        v = queue.popleft()
        print(v, end=' ')
        for neighbor in graph[v]:
            if not visited[neighbor]:
                queue.append(neighbor)
                visited[neighbor] = True

# 입력 받기
N, M, V = map(int, input().split())  # 정점 수, 간선 수, 시작 정점
graph = [[] for _ in range(N + 1)]

# 간선 정보 입력 받기
for _ in range(M):
    u, v = map(int, input().split())
    #양방향 그래프이기 때문에
    graph[u].append(v)
    graph[v].append(u)

# 각 정점의 인접 리스트를 정렬
for edges in graph:
    edges.sort()

# DFS와 BFS 결과 출력
visited_dfs = [False] * (N + 1)
dfs(V, visited_dfs, graph)
print()  # 줄바꿈
bfs(V, graph)

[백준] 1260번: DFS와 BFS - 파이썬

🔈 문제 그래프를 DFS로 탐색한 결과와 BFS로 탐색한 결과를 출력하는 프로그램을 작성하시오. 단, 방문할 수 있는 정점이 여러 개인 경우에는 정점 번호가 작은 것을 먼저 방문하고, 더 이상 방

lazypazy.tistory.com


1920 수 찾기

N개의 정수 A[1], A[2], …, A[N]이 주어져 있을 때, 이 안에 X라는 정수가 존재하는지 알아내는 프로그램을 작성하시오.
 
첫째 줄에 자연수 N(1 ≤ N ≤ 100,000)이 주어진다. 다음 줄에는 N개의 정수 A[1], A[2], …, A[N]이 주어진다. 다음 줄에는 M(1 ≤ M ≤ 100,000)이 주어진다. 다음 줄에는 M개의 수들이 주어지는데, 이 수들이 A안에 존재하는지 알아내면 된다. 모든 정수의 범위는 -231 보다 크거나 같고 231보다 작다.
 
M개의 줄에 답을 출력한다. 존재하면 1을, 존재하지 않으면 0을 출력한다.


[순차 탐색은 시간초과가 나온다.]

# 순차 탐색으로 구현
def sequential_search(n, target, array):
    # 각 원소를 하나씩 확인하며
    for i in range(n):
        # 현재의 원소가 찾고자 하는 원소와 동일한 경우
        if array[i] == target:
            return 1 # 찾으면 1 반환
    return 0 #찾지 못하면 0 반환
#N
N = int(input())
# 생성된 리스트
array = list(map(int, input().split()))
# 배열 길이가 N과 일치하는지 확인
if len(array) != N:
    raise ValueError(f"Expected {N} elements for the main array, but got {len(array)} elements.")

#M
M = int(input())
# 확인할 리스트
checkArray = list(map(int, input().split()))
# 배열 길이가 M과 일치하는지 확인
if len(checkArray) != M:
    raise ValueError(f"Expected {M} elements for the check array, but got {len(checkArray)} elements.")

# checkArray의 각 요소에 대해 sequential_search 실행
for target in checkArray:
    print(sequential_search(N, target, array))

 
[이진탐색으로 해야 시간초과가 나오지 않는다.]

def binary_search(target, array):
    low, high = 0, len(array) - 1
    while low <= high:  # 검색해야 할 레코드가 있는 경우
        middle = (low + high) // 2  # middle 계산
        if target == array[middle]:  # 탐색 성공
            return 1  # 1 출력
        elif target < array[middle]:  # 왼쪽 부분 리스트 탐색
            high = middle - 1
        else:  # 오른쪽 부분 리스트 탐색
            low = middle + 1
    return 0  # 탐색 실패 -> 0 출력

# N 입력 및 배열 생성
N = int(input())
array = list(map(int, input().split()))
array.sort()  # 이진 탐색을 위해 배열을 정렬

# M 입력 및 확인할 리스트 생성
M = int(input())
checkArray = list(map(int, input().split()))

# checkArray의 각 요소에 대해 이진 탐색 실행
for target in checkArray:
    print(binary_search(target, array))

 

'문제풀이' 카테고리의 다른 글

[자료구조와알고리즘with파이썬] ch.5  (0) 2024.10.15
[BOJ 2840] 행운의 바퀴  (3) 2024.10.01