Skip to content

Conversation

@fnzksxl
Copy link
Member

@fnzksxl fnzksxl commented Jan 15, 2024

🔗 문제 링크

부대 복귀

✔️ 소요된 시간

20분

✨ 수도 코드

문제를 처음 읽었을 때, 그래프를 이용해야 겠다. 라는 생각이 최우선적으로 들었다.

문제 발췌
두 지역 간의 길을 통과하는 데 걸리는 시간은 모두 1로 동일합니다.
-> 가중치가 없다.
임무를 수행한 각 부대원은 지도 정보를 이용하여 최단시간에 부대로 복귀하고자 합니다
-> 최소 거리로 탐색해야한다.

목적지(Destination)이 하나고, 부대원(Sources)이 리스트로 주어져서 복수였으므로,
부대원->목적지로 거리를 계산하는 것보다 목적지->부대원까지의 거리를 계산하는 것이 더 쉬워보였다.
따라서 다익스트라 알고리즘을 문제에 구현해서 풀어보려고 한다.

  1. 부대원에서 목적지로 가려할 때
    image

각 부대원의 위치에서 목적지까지 탐색을 해야함. (총 부대원 수만큼 경로 탐색)

  1. 목적지에서 부대원까지 거리 탐색
    image

목적지에서 부대원까지 한 번의 알고리즘으로 탐색. (간편)

다익스트라 알고리즘은 하나의 정점에서 나머지 모든 정점들까지의 최소 거리를 계산하는 알고리즘이다.

전체 코드

from heapq import heappop, heappush

def solution(n, roads, sources, destination):
    answer = []
    graph=[[] for _ in range(n+1)]
    
    for start, dest in roads:
        graph[start].append(dest)
        graph[dest].append(start)
    
    # 문제에서 정점의 개수가 < 100,000 인데
    # 밑에 roads의 조건과 헷갈려서 500001로 한 것 같다.. 
    INF = 500001
    distances = [INF] * (n+1)
    distances[destination] = 0
    
    queue = []
    
    heappush(queue, (distances[destination], destination))
    
    while queue:
        cur_dist, cur_dest = heappop(queue)

        if distances[cur_dest] < cur_dist:
            continue

        for next_dest in graph[cur_dest]:
            distance = cur_dist + 1
            if distance < distances[next_dest]:
                distances[next_dest] = distance
                heappush(queue, (distance, next_dest))
            
    return [-1 if distances[s] == INF else distances[s] for s in sources]

📚 새롭게 알게된 내용

PR 날리기 전에 브랜치 파놓고 실수로 switch를 안 해서 main에 커밋 때려버렸었는데요..
전에는 revert 사용해서 실수한 커밋 내역을 남겼었는데,
이번에는 reset을 이용해서 완벽 범죄를 저지르는 방법을 알게 되었습니다

@alstjr7437
Copy link
Member

오호 다익스트라 알고리즘으로 푸셨네요!! 따로 heappush, heappop 함수 사용하는 것도 신기하네요!
따로 BFS로도 풀릴 것 같은데 조금 더 실력이 쌓이게 된다면 나중에 도전해봐야 겠네요!!

그리고 reset을 사용하니 진짜 언제한지도 모르게 날라갔군요 ㄷ..

Copy link
Member

@tgyuuAn tgyuuAn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

와 이 문제 진짜 인사이트 넓히기 좋아요.

목적지(Destination)이 하나고, 부대원(Sources)이 리스트로 주어져서 복수였으므로,

부대원->목적지로 거리를 계산하는 것보다 목적지->부대원까지의 거리를 계산하는 것이 더 쉬워보였다.

따라서 다익스트라 알고리즘을 문제에 구현해서 풀어보려고 한다.

와 이게 이 문제 핵심인데,

이걸 바로 캐치하시는게 대단하시네요 ;;; 다익스트라 짬밥이 있으신가봐요..




AlgoLeadMe/AlgoLeadMe-1#3

이거 1팀 스터디에서도 나왔던 문젠데 처음 저 아이디어 보고 머리를 한 대 탁 쳤던 기억이 있네요.

안 풀어보신 분들 이 문제 다익스트라 인사이트 넓히기 좋은 문제로 강추 드립니다!

@fnzksxl
Copy link
Member Author

fnzksxl commented Jan 16, 2024

@alstjr7437

heapq. ~~ 로 쓰기 귀찮아서 처음부터 from으로 불러오는게 뭔가 편안하더라구요..
다른 분들은 어떻게 풀었나 참고해봤는데 비슷비슷한 거 같아요

여담인데 민석님 PR에는 코멘트가 답글처럼 된 것도 있던데 어떻게 하나요..?

@fnzksxl
Copy link
Member Author

fnzksxl commented Jan 16, 2024

@tgyuuAn

비슷한 문제를 옛날에 풀었던 기억이 있어서 바로 떠오른 것 같습니다. 그리디 알고리즘 문제들은 나오면 머리가 띵해지는데 혹시 추천해주실 만한 문제가 있을까요??

@tgyuuAn
Copy link
Member

tgyuuAn commented Jan 17, 2024

@fnzksxl

그리디, DP, 분할정복 진짜 머리 띵해지는 거 인정입니다...

재밌게 풀었던 그리디 몇개 추려봤씁니다.

이전 수열은 어떤 수열일까, 요격 시스템, 택배 배달과 수거하기, 소트 정도 있씁니다.




추가적으로 문제 마땅히 풀만한 거 없을 때,

알고리즘 스터디 다른 레포지토리 들어가셔서 스터디 참가원 폴더 클릭하시면 풀었던 문제들 보실 수 있는데,

거기서 문제 유형 보시면서 맛있게 생긴거 하나 푸시면 좋아요!

상세히 적힌 PR도 있으니까 안풀리면 풀이도 볼 수 있죠!

@SeongHoonC
Copy link
Collaborator

음.. 처음에 역시나 다익스트라로 풀었는데 바로 시간초과에 메모리초과 떠버리고
bfs 로 바꿨네요..

import java.util.*

class Solution {
    fun solution(n: Int, roads: Array<IntArray>, sources: IntArray, destination: Int): IntArray {
        val graph = Array (n+1) { Array(n+1) { false }}

        roads.forEach { road ->
            graph[road[0]][road[1]] = true
            graph[road[1]][road[0]] = true
        }

        val distance = Array(n + 1) { -1 }

        bfs(destination, graph, distance)
        return sources.map { distance[it] }.toIntArray()
    }

    private fun bfs(start: Int, graph: Array<Array<Boolean>>, distance: Array<Int>) {
        val deque = ArrayDeque<Int>()
        deque.add(start)
        distance[start] = 0

        while (deque.isNotEmpty()) {
            val now = deque.removeFirst()
            for(i in 1 until graph.size){
                if(graph[now][i] && distance[i] == -1) {
                    distance[i] = distance[now] + 1
                    deque.add(i)
                }
            }
        }
    }
}

이중 배열을 쓰면 안되나봐요. 시간을 너무 많이써서 여기까지 하겠습니다!

@fnzksxl
Copy link
Member Author

fnzksxl commented Jan 18, 2024

@SeongHoonC 힙으로 다익스트라 구현하면 시간 훨씬 줄어들긴 합니다!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants