[파이썬] 백준 14466 : 소가 길을 건너간 이유 6 (골드 4)
14466번: 소가 길을 건너간 이유 6
첫 줄에 N, K, R이 주어진다. 다음 R줄에는 한 줄에 하나씩 길이 주어진다. 길은 상하좌우로 인접한 두 목초지를 잇고, r c r′ c′의 형태 (행, 열, 행, 열)로 주어진다. 각 수는 1 이상 N 이하이다.
www.acmicpc.net
문제
풀이
0. 방향성 생각
- 각 소에서 BFS를 돌려서 도달하지 못하는 소의 수를 카운트한다.
- 다리가 있는 간선을 이용해야하면 이동하지 않는다.
- 쌍을 구하는 문제이므로 A->B, B->A 이런식으로 중복으로 카운팅이 된다.
- 이를 제거하기 위해서 소의 수를 모두 구한 후 2로 나누어주기.
1. 입력
from collections import deque
import sys
input = lambda : sys.stdin.readline().rstrip()
N,K,R = map(int,input().split())
arr = [[0]*(N+1) for _ in range(N+1)]
graph = set() # 간선 입력
for _ in range(R):
y1,x1,y2,x2 = map(int,input().split())
graph.add((x1,y1,x2,y2))
graph.add((x2,y2,x1,y1))
cow = {} # 소 입력. 인덱스 필요
for i in range(K):
y,x = map(int,input().split())
arr[y][x] = 1
cow[(x,y)] = i
inside = lambda x,y : 1<=x<=N and 1<=y<=N
dire = [(1,0),(-1,0),(0,1),(0,-1)]
- 특수한 간선인 다리는 set으로 처리한다. 양방향으로 처리를 해준다.
- 해시 대신 3차원 리스트를 만들어서 들어오는 방향에 따라서 boolean 형태로 나눠도 괜찮을 듯
- BFS에서 각 소를 구분하기 위해서 인덱스를 활용한다.
2. 함수 정의
def bfs(x,y,idx):
visit = [[False]*(N+1) for _ in range(N+1)]
visit[y][x] = True
C = [True]*K # 도달할 수 있는 소는 False
C[idx] = False
q = deque([(x,y)])
while q:
x,y = q.popleft()
for dx,dy in dire:
nx,ny = x+dx,y+dy
if inside(nx,ny) and not visit[ny][nx] and (x,y,nx,ny) not in graph:
visit[ny][nx] = True
q.append((nx,ny))
if arr[ny][nx] == 1:
C[cow[(nx,ny)]] = False
return sum(C) # 어떤 소가 만나지 못하는 소의 수
- 도달할 수 있는 소를 나타내는 배열 C가 있다.
- 어떤 소에 도달할 수 있으면, 그 소를 False로 만든다
- sum(C)에는 어떤 소가 만나지 못하는 소의 수이다.
3. 출력
answer = 0
for idx,(x,y) in enumerate(cow):
answer += bfs(x,y,idx)
print(answer//2) # 중복 제거
- 중복 제거하기위해 나누기 2
전체코드
from collections import deque
import sys
input = lambda : sys.stdin.readline().rstrip()
N,K,R = map(int,input().split())
arr = [[0]*(N+1) for _ in range(N+1)]
graph = set() # 간선 입력
for _ in range(R):
y1,x1,y2,x2 = map(int,input().split())
graph.add((x1,y1,x2,y2))
graph.add((x2,y2,x1,y1))
cow = {} # 소 입력. 인덱스 필요
for i in range(K):
y,x = map(int,input().split())
arr[y][x] = 1
cow[(x,y)] = i
inside = lambda x,y : 1<=x<=N and 1<=y<=N
dire = [(1,0),(-1,0),(0,1),(0,-1)]
def bfs(x,y,idx):
visit = [[False]*(N+1) for _ in range(N+1)]
visit[y][x] = True
C = [True]*K # 도달할 수 있는 소는 False
C[idx] = False
q = deque([(x,y)])
while q:
x,y = q.popleft()
for dx,dy in dire:
nx,ny = x+dx,y+dy
if inside(nx,ny) and not visit[ny][nx] and (x,y,nx,ny) not in graph:
visit[ny][nx] = True
q.append((nx,ny))
if arr[ny][nx] == 1:
C[cow[(nx,ny)]] = False
return sum(C) # 어떤 소가 만나지 못하는 소의 수
answer = 0
for idx,(x,y) in enumerate(cow):
answer += bfs(x,y,idx)
print(answer//2) # 중복 제거
코멘트
.
'Algorithm > Graph' 카테고리의 다른 글
[파이썬] 프로그래머스 : 표 병합 (레벨3) (0) | 2024.02.25 |
---|---|
[파이썬] 백준 16954 : 움직이는 미로탈출 (골드3) (0) | 2024.02.19 |
[파이썬] 백준 9347 : 울타리 (골드3) (0) | 2024.02.18 |
[파이썬] 백준 1162 : 도로포장 (플레5) (0) | 2023.12.25 |
[파이썬] 백준 15806 : 영우의 기숙사 청소 (플레5) (0) | 2023.12.23 |
[파이썬] 백준 23034 : 조별과제 멈춰 (플레5) (0) | 2023.12.22 |
[파이썬] 백준 1944 : 복제 로봇 (골드1) (0) | 2023.12.19 |
댓글