내용으로 건너뛰기
테페리넷
사용자 도구
등록
로그인
사이트 도구
검색
도구
문서 보기
Fold/unfold all
역링크
미디어 관리자
사이트맵
등록
로그인
>
미디어 관리자
사이트맵
현재 위치:
테페리넷
»
Problem Solving
»
문제
»
백준 온라인 저지 (BOJ)
»
도로 정비하기
ps:problems:boj:1739
이 문서는 읽기 전용입니다. 원본을 볼 수는 있지만 바꿀 수는 없습니다. 문제가 있다고 생각하면 관리자에게 문의하세요.
====== 도로 정비하기 ====== ===== 풀이 ===== * 출발점과 도착점의 가로 좌표와 세로 좌표가 모두 다르다면, 갈수있는 가능한 경로는 두가지이다. 출발점에서 연결된 가로방향 도로와 세로방향 도로를 h1과 v1 이라 하고, 도착점에 연결된 도로들을 h2와 v2라고 한다면, 가능 경로는 h1->v2 또는 v1->h2 이다. * 이제, 도착점이 출발점보다 오른쪽 위에 있다면, h1이 오른쪽방향이면서 v2가 위쪽 방향이든가, v1이 위쪽방향이면서 h2가 오른쪽방향이어야 한다. 이러한 조건들은 각각의 도로들을 변수로 갖는 [[ps:2-sat]] 형태로 만들수 있다. (h1 and v2) or (v1 and h2) 와 같은 식은 분배법칙으로 풀어주면 (h1 or v1) and (h1 or h2) and (v2 or v1) and (v2 or h2) 형태의 2-CNF로 만들수 있다 * 출발점과 도착점의 가로좌표가 일치하는 경우에는, 세로방향 도로로만 이동해야 하고, 그 도로의 방향을 고정시켜주면 된다. v1이 위쪽방향이라는 조건은 (v1 or v1) 으로 처리할수 있다. 출발점과 도착점의 세로좌표가 일치하는 경우에는 가로도로에 대해서 똑같이 조건을 넣으면 된다. * 이렇게 식을 모두 만든뒤에 [[ps:2-SAT]]의 해가 존재하는지를 찾으면 된다. 변수의 갯수는 O(N+M)개, 2-CNF식의 절의 갯수는 O(K)개가 나오므로, 총 시간복잡도는 O(N+M+K)가 된다. ===== 코드 ===== <dkpr py> """Solution code for "BOJ 1739. 도로 정비하기". - Problem link: https://www.acmicpc.net/problem/1739 - Solution link: http://www.teferi.net/ps/problems/boj/1739 Tags: [2-Sat] """ import sys from teflib import twosat def main(): T = int(sys.stdin.readline()) for _ in range(T): N, M, K = [int(x) for x in sys.stdin.readline().split()] two_sat = twosat.TwoSat(N + M) for _ in range(K): A, B, C, D = [int(x) for x in sys.stdin.readline().split()] if A == C and B == D: continue h1, v1, h2, v2 = A - 1, B + N - 1, C - 1, D + N - 1 if B < D: h1, h2 = ~h1, ~h2 if A < C: v1, v2 = ~v1, ~v2 if A == C: two_sat.x_or_y(h1, h1) elif B == D: two_sat.x_or_y(v1, v2) else: # (h1 and v2) or (v1 and h2) two_sat.x_or_y(h1, v1) two_sat.x_or_y(h1, h2) two_sat.x_or_y(v2, v1) two_sat.x_or_y(v2, h2) print('Yes' if two_sat.is_satisfiable() else 'No') if __name__ == '__main__': main() </dkpr> * Dependency: [[:ps:teflib:twosat#TwoSat|teflib.twosat.TwoSat]] {{tag>BOJ ps:problems:boj:플래티넘_1}}
ps/problems/boj/1739.txt
· 마지막으로 수정됨: 2022/11/03 15:30 저자
teferi
문서 도구
문서 보기
역링크
Fold/unfold all
맨 위로