Notice
Recent Posts
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Archives
관리 메뉴

교대최소제곱법

[백준 파이썬 1432번 그래프 수정] 생각의 전환의 전환 with 위상정렬 본문

코딩테스트

[백준 파이썬 1432번 그래프 수정] 생각의 전환의 전환 with 위상정렬

옐라크레 2023. 10. 25. 15:12

 

https://www.acmicpc.net/problem/1432

 

1432번: 그래프 수정

첫째 줄에 정점의 개수 N이 주어진다. 둘째 줄부터 N개의 줄에는 인접행렬 형식으로 입력이 주어진다. 0은 연결되지 않았음을 의미하고, 1은 연결되었다는 것을 의미한다. N은 50보다 작거나 같은

www.acmicpc.net

 

이번 문제의 핵심은 

답이 여러 개일 경우에는 사전 순으로 제일 앞서는 것을 출력한다.

 

사실 중복되는 답을 찾는 것은 위상정렬만 알면 어렵지 않다. 하지만 사전 순이 매우 큰 난관이었다.

 

핵심적인 아이디어는

1. 반대로 위에서 내려오는 방식으로 생각할 것

2. 최대 힙을 활용해 큰 인덱스부터 찾을 것

 

1번까지는 스스로 생각했는데 2번을 생각하지 못해 해결하지 못했다.

"거꾸로 생각해도 작은 것부터 찾으니까 어짜피 똑같네" 라고 판단해버렸다.

 

힙을 사용할 생각도 했는데 이번에는 1번과 합치지 못해서 실패...

1번과 2번을 동시에 생각할 수 있어야 풀 수 있었던 문제

 

from heapq import heappop, heappush


def topo():
    heap = []
    result_ls = []
    for i in range(1, N + 1):
        if check[i] == 0:
            heappush(heap, -i)

    while heap:
        now = -heappop(heap)
        result_ls.append(now)
        for nxt in graph[now]:
            check[nxt] -= 1
            if check[nxt] == 0:
                heappush(heap, -nxt)

    if len(result_ls) == N:
        num = 1
        ans_ls = [0 for _ in range(N+1)]
        for ans in reversed(result_ls):
            ans_ls[ans] = num
            num += 1
        print(*ans_ls[1:])

    else:
        print(-1)


N = int(input())
graph = [[] for _ in range(N+1)]
check = [0 for _ in range(N+1)]
for i in range(1, N+1):
    rows = '0'+input()
    for j in range(1, N+1):
        if rows[j] == '1':
            check[i] += 1
            graph[j].append(i)

topo()

 

 

[백준 python] 1432번 그래프 수정

[백준 python] 1432번 그래프 수정 레벨: 플레티넘5 언어: 파이썬 📑풀이 과정 이 문제는 정글 ㅇㅎㅈ님의 설명을 듣고 이해한 문제이다. 감사합니다ㅎㅎ V1 → V2로 연결된 간선이 있을때, V2의 번호

wonyoung2257.tistory.com