[백준 바킹독] 0x09 - BFS 토마토(7576)
Introduction
그래프는 다대다의 연결관계를 표현합니다. 정점들의 집합과 이들을 연결하는 간선들의 집합으로 구성된 자료구조입니다.
정점(Vertex) : 그래프의 구성요소로 하나의 연결점 인접 정점 : 두 개의 정점 간 간선이 존재하면 인접하다고 함 간선(Edge) : 두 정점을 연결하는 선 차수(Degree) : 정점 하나에 연결된 간선의 수 V 개의 정점을 갖는 그래프의 최대 간선의 수는 V * (V-1) / 2 (무향 그래프 - 양방향)
사이클 없는 유향, 방향 그래프(DAG, Directed Acyclic Graph) : 순환되지 않는 방향 그래프, 각 간선의 끝을 따라가면 원래의 정점으로 돌아오지 않음
경로(Path)란 어떤 정점에서 시작하여 다른 정점으로 끝나는 순회로 두 정점 사이를 잇는 간선들을 순서대로 나열한 것을 말합니다.
너비우선 탐색은 탐색 시작점의 인접한 정점들을 먼저 모두 차례로 방문한 후에 방문했던 정점을 시작점으로 하여 다시 인접한 정점들을 차례로 방문하는 방식입니다. 따라서 선입선출 형태의 큐 자료구조를 활용하여 만듭니다.
탐색의 과정 중 정점에 도착한 경로가 있을 때, 해당 경로는 시작 정점과 해당 정점에 대한 최단 경로입니다.
from collections import deque
import sys
input = sys.stdin.readline
n, m, start = map(int, sys.stdin.readline().strip().split())
edge = [[] for _ in range(n + 1)]
for _ in range(m):
v1, v2 = map(int, sys.stdin.readline().strip().split())
edge[v1].append(v2)
edge[v2].append(v1)
for e in edge:
e.sort()
def bfs(x):
queue = deque([start])
b_check = [False for _ in range(n+1)]
b_check[start] = True
while queue:
node = queue.popleft()
if node not in edge:
visit.append(node)
queue.extend(graph[node])
return visit
시작 정점의 한 방향으로 갈 수 있는 경로가 있는 곳까지 깊이 탐색해가다가 더 이상 갈 곳이 없게 되면 가장 마지막에 만났던 갈림길 간선이 있는 정점으로 되돌아와서 다른 방향의 정점으로 탐색을 계속 반복하여 결국 모든 정점을 방문하는 순회 방법입니다.
가장 마지막에 만났던 갈림길의 정점으로 되돌아가서 탐색하므로 후입선출 구조로 구현합니다. 메모리 스택을 활용한 재귀 함수, 혹은 직접 스택에 탐색 내용을 사용합니다.
DFS 구현 (stack)
graph = {
'A': ['B'],
'B': ['A', 'C', 'H'],
'C': ['B', 'D'],
'D': ['C', 'E', 'G'],
'E': ['D', 'F'],
'F': ['E'],
'G': ['D'],
'H': ['B', 'I', 'J', 'M'],
'I': ['H'],
'J': ['H', 'K'],
'K': ['J', 'L'],
'L': ['K'],
'M': ['H']
}
def dfs(graph, start_node):
visit = list()
stack = list()
stack.append(start_node)
while stack:
node = stack.pop()
if node not in visit:
visit.append(node)
stack.extend(graph[node])
return visit
DFS 구현 (재귀)
import sys
sys.setrecursionlimit(10 ** 9)
input = sys.stdin.readline
# dfs(V, E, R) { # V : 정점 집합, E : 간선 집합, R : 시작 정점
# visited[R] <- YES; # 시작 정점 R을 방문 했다고 표시한다.
# for each x ∈ E(R) # E(R) : 정점 R의 인접 정점 집합.(정점 번호를 오름차순으로 방문한다)
# if (visited[x] = NO) then dfs(V, E, x);
# }
N, M, R = map(int, input().split())
graph = [[] for i in range(N+1)]
for _ in range(M):
u, v = map(int, input().split())
graph[u].append(v)
graph[v].append(u)
for g in graph:
g.sort()
visit = [0]*(N+1)
cnt = 1
def dfs(R):
global cnt
visit[R] = cnt
for x in graph[R]:
if visit[x] == 0:
cnt+=1
dfs(x)
dfs(R)
for i in range(1,N+1):
print(visit[i])
https://www.acmicpc.net/step/24
주의) 파이썬의 기본 재귀 깊이 제한은 1000이므로 재귀문제를 활용할 때 아래와 같이 설정을 해두어야 에러메시지가 발생하지 않는다.
import sys
sys.setrecursionlimit(10 ** 6)
특이사항
import sys
sys.setrecursionlimit(10 ** 9)
input = sys.stdin.readline
# dfs(V, E, R) { # V : 정점 집합, E : 간선 집합, R : 시작 정점
# visited[R] <- YES; # 시작 정점 R을 방문 했다고 표시한다.
# for each x ∈ E(R) # E(R) : 정점 R의 인접 정점 집합.(정점 번호를 오름차순으로 방문한다)
# if (visited[x] = NO) then dfs(V, E, x);
# }
N, M, R = map(int, input().split())
graph = [[] for i in range(N+1)]
for _ in range(M):
u, v = map(int, input().split())
graph[u].append(v)
graph[v].append(u)
for g in graph:
g.sort()
visit = [0]*(N+1)
cnt = 1
def dfs(R):
global cnt
visit[R] = cnt
for x in graph[R]:
if visit[x] == 0:
cnt+=1
dfs(x)
dfs(R)
for i in range(1,N+1):
print(visit[i])
특이사항
import sys
input = sys.stdin.readline
sys.setrecursionlimit(10**6)
N, M, R = 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 g in graph:
g.sort(reverse=True)
visited = [0]*(N+1)
cnt = 1
def dfs(R):
global cnt
visited[R] = cnt
for x in graph[R]:
if visited[x] == 0:
cnt += 1
dfs(x)
dfs(R)
for i in range(1,len(visited)):
print(visited[i])
특이사항
import sys
from collections import deque
sys.setrecursionlimit(10**6)
input = sys.stdin.readline
N, M, R = 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 g in graph:
g.sort()
cnt = 1
def dfs(R):
global cnt
visited = [0]*(N+1)
visited[R] = cnt
queue = deque([R])
while queue:
u = queue.popleft()
for v in graph[u]:
if visited[v] == 0:
cnt += 1
visited[v] = cnt
queue.extend([v])
return visited
visited = dfs(R)
for i in range(1,len(visited)):
print(visited[i])
특이사항
import sys
from collections import deque
sys.setrecursionlimit(10**6)
input = sys.stdin.readline
N, M, R = 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 g in graph:
g.sort(reverse=True)
cnt = 1
def bfs(R):
global cnt
visit = [0]*(N+1)
visit[R] = cnt
queue = deque([R])
while queue:
u = queue.popleft()
for v in graph[u]:
if visit[v] == 0:
cnt += 1
visit[v] = cnt
queue.extend([v])
return visit
visit = bfs(R)
for i in range(1,len(visit)):
print(visit[i])
import sys
from collections import deque
sys.setrecursionlimit(10**6)
input = sys.stdin.readline
N = int(input())
M = int(input())
graph = [[] for _ in range(N+1)]
for _ in range(M):
u, v = map(int,input().split())
graph[u].append(v)
graph[v].append(u)
cnt = 1
def search(R):
global cnt
visit = [0]*(N+1)
visit[R] = cnt
queue = deque([R])
while queue:
u = queue.popleft()
for v in graph[u]:
if visit[v] == 0:
cnt += 1
visit[v] = cnt
queue.extend([v])
return visit
visit = search(1)
result = -1
for v in visit:
if v != 0:
result +=1
print(result)
import sys
from collections import deque
sys.setrecursionlimit(10**6)
input = sys.stdin.readline
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 g in graph:
g.sort()
d_visit = [False]*(N+1)
d_search_list = []
def dfs(V):
d_visit[V] = True
d_search_list.append(V)
for x in graph[V]:
if d_visit[x] == False:
dfs(x)
def bfs(V):
visit = [False]*(N+1)
visit[V] = True
search_list = [V]
queue = deque([V])
while queue:
u = queue.popleft()
for v in graph[u]:
if visit[v] == False:
visit[v] = True
search_list.append(v)
queue.extend([v])
return search_list
dfs(V)
b_search_list = bfs(V)
d_output = ''
for d in d_search_list:
d_output = d_output + str(d) + ' '
d_output = d_output[:-1]
b_output = ''
for b in b_search_list:
b_output = b_output + str(b) + ' '
b_output = b_output[:-1]
print(d_output)
print(b_output)
https://www.acmicpc.net/problem/2667
import sys
input = sys.stdin.readline
class searching():
def __init__(self,maps):
self._maps = maps
self._count_house = []
self._cnt = 0
def _dfs(self,row,col):
if row < 0 or row >= len(self._maps) or col < 0 or col >= len(self._maps[0]):
return
if self._maps[row][col] == '0':
return
self._maps[row][col] = '0'
self._dfs(row-1,col)
self._dfs(row+1,col)
self._dfs(row,col-1)
self._dfs(row,col+1)
self._cnt += 1
def search(self):
for i in range(len(self._maps)):
for j in range(len(self._maps[0])):
if self._maps[i][j] == '1':
self._cnt = 0
self._dfs(i,j)
self._count_house.append(self._cnt)
return self._count_house
N = int(input())
maps = []
for _ in range(N):
lists = []
strings = input().rstrip("\n")
for s in strings:
lists.append(s)
maps.append(lists)
func = searching(maps)
result = func.search()
result.sort()
print(len(result))
for r in result:
print(r)
땅의 모습이 아니라 배추의 위치가 주어지는 문제
https://www.acmicpc.net/problem/1012
import sys
sys.setrecursionlimit(10**6)
input = sys.stdin.readline
class searching():
def __init__(self,map):
self._map = map
self._cnt = 0
def _dfs(self,row,col):
if row < 0 or row >= len(self._map) or col < 0 or col >= len(self._map[0]):
return
if self._map[row][col] == '0':
return
self._map[row][col] = '0'
self._dfs(row-1,col)
self._dfs(row+1,col)
self._dfs(row,col-1)
self._dfs(row,col+1)
def search(self):
for i in range(len(self._map)):
for j in range(len(self._map[0])):
if self._map[i][j] == '1':
self._cnt += 1
self._dfs(i,j)
return self._cnt
T = int(input())
for _ in range(T):
M, N, K = map(int,input().split())
maps = [['0']*M for _ in range(N)]
for _ in range(K):
i, j = map(int,input().split())
maps[j][i] = '1'
func = searching(maps)
print(func.search())
BFS의 특징은 각 정점을 최단경로로 방문한다는 것입니다. 이 점을 활용해 최단거리를 구해 봅시다.
import sys
from collections import deque
input = sys.stdin.readline
class searching():
def __init__(self,map):
self._map = map
self._cnt = 0
def bfs(self,row,col):
q = deque([(row,col,1)])
while q:
r, c, dist = q.popleft()
# 도착
if r == len(self._map)-1 and c == len(self._map[0])-1:
break
# 탐색
if self._map[r][c] == '1':
self._map[r][c] = '0'
if r - 1 >= 0: q.extend([(r-1,c,dist+1)])
if r + 1 < len(self._map): q.extend([(r+1,c,dist+1)])
if c - 1 >= 0: q.extend([(r,c-1,dist+1)])
if c + 1 < len(self._map[0]): q.extend([(r,c+1,dist+1)])
return dist
N, M = map(int,input().split())
maps = []
for _ in range(N):
lists = []
string = input().rstrip("\n")
for s in string:
lists.append(s)
maps.append(lists)
func = searching(maps)
print(func.bfs(0,0))
또 다른 BFS 최단거리 연습문제
import sys
from collections import deque
input = sys.stdin.readline
def bfs(n,k):
q = deque([(n,0)])
check = [0]*100001
while q:
point, time = q.popleft()
# print(point,time)
if point == k:
break
if check[point] == 0:
check[point] = 1
if point*2 < len(check): q.extend([(point*2,time+1)])
if point+1 < len(check): q.extend([(point+1,time+1)])
if point-1 >= 0: q.extend([(point-1,time+1)])
return time
N, K = map(int,input().split())
print(bfs(N,K))
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
1167 트리의 지름
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Git 명령어를 사용한 하위 디렉토리 다운로드 Clone 할 로컬 저장소 생성
Introduction
# Fetch the submodule commits into the main repository git remote add submodule_origin git://url/to/submodule/origin git fetch submodule_origin
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Graph
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Introduction
Spring Project
the page for java
가벼운 Base image를 사용
version: 3.0.0a10
WIDTH
version: 3.0.0a10
#include <iostream> #include <thread> #include <chrono> #include <mutex> #include <atomic> #include <string.h>
version: 3.0.0a10
https://cplusplus.com/reference/future/
Multithreading support was introduced in C++11.
how to costom github blog using jekyll
You’ll find this post in your _posts directory. Go ahead and edit it and re-build the site to see your changes. You can rebuild the site in many different wa...