알고리즘

프로그래머스(programmers) 순위 python 정답[Graph, 플로이드와샬]

TheSapper 2023. 2. 6. 05:08
반응형

프로그래머스(programmers) 순위 python 정답[Graph, 플로이드와샬 알고리즘]

문제 링크

https://school.programmers.co.kr/learn/courses/30/lessons/49191

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

문제 정답

def solution(n, results):
    dist_graph = [[0]*n for _ in range(n)]
    # 그래프 연결
    for w, l in results :
        dist_graph[w-1][l-1] =1
    # 플로이드 와샬
    for k in range(n):
        for w in range(n):
            for l in range(n):
            	# 진 플로이드 와샬
            	# dist_graph[w][l] = min(dist_graph[w][l], dist_graph[w][k] +  dist_graph[k][l])
                if dist_graph[w][l]== 0 and dist_graph[w][k] !=0 and dist_graph[k][l] !=0:
                    dist_graph[w][l] = 1
                
    winner_list = [0] * n
    loser_list = [0] * n
    # l열의 1 합 : l이 진 멤버 수
    # w행의 1 합 : w가 이긴 멤버 수
    for w in range(n):
        for l in range(n):
            loser_list[l] += dist_graph[w][l]
            winner_list[w] += dist_graph[w][l]    
    answer = 0
    # 특정 멤버를 이긴 사람 수 + 진 사람 수가 n-1면 순위를 결정할 수 있다.
    for index in range(n):
        if winner_list[index] + loser_list[index] == n-1:
            answer+=1

                                
    return answer

플로이드 와샬 알고리즘을 응용한다.

 

플로이드 와샬 알고리즘은 다익스트라 알고리즘이랑 유사한데,

큐를 사용하는 다익스트라와 다르게,

2차원 배열을 활용하여, 각 점(i,j)을 중간점(k)을 거쳐 이동한 거리의 최소값을 계산한다.

이 문제의 경우는, 최소 거리를 계산하는 대신, 연결되었으면 강제로 1로 표시해서 승패 판단 가능 여부를 나타낸다.

  • A[i][j]가 1이면 i 관점에선 이긴거고 j 관점에선 진거다.

순위를 판단하려면, n 선수중에 n-1명과의 승패 여부를 추론할 수 있어야 한다.

플로이드 와샬로 초기화 하면 아래와 같은 배열이 나온다.

[0, 1, 0, 0, 1]
[0, 0, 0, 0, 1]
[0, 1, 0, 0, 1]
[0, 1, 1, 0, 1]
[0, 0, 0, 0, 0]

각 행의 1의 갯수는 다음을 의미한다.

  • > 행의 1 갯수(합) : 이긴 멤버 수
  • ^ 열의 1 갯수(합) : 진 멤버 수

따라서 행합 +열합이 n-1이면, 순위 판단이 가능하다.

 

주어진 정보로 n 선수의 유추 가능한 모든 승패 결과를 1로 표시히면,

5(idx=4)번 선수는 아무에게도 이기지 못했으며, 4명와 승부 시 패배핸다는 것을 알 수 있다.

따라서 5번 선수는 5위이다.

 

또한 2번(idx=1) 선수는 5위한테만 이기며, 1,3,4와 승부 결과 패배함을 알 수 있다.

따라서 2번 선수는 4위이다.

 

이를 winner_list(행합), loser_list(열합)으로 계산하여, index를 이용해 합이 n-1인지 체크하면, 해당 선수의 순위를 알 수 있다.

 

반응형