프로그래밍/알고리즘

BOJ 1238 · 파티

반응형


알고리즘 분류 : 다익스트라  


각 학생이 각자 자신의 마을에서 출발하고, X 마을에서 파티를 하고, 다시 자신의 마을로 돌아오는 시간을 맞추는 문제다. 마을 간의 이동은 1 이상의 소요 시간이 걸리므로, 다익스트라 알고리즘을 이용해야 한다.


  • 이 문제는 다익스트라 알고리즘을 두 번만 호출해서 해결할 수 있다.
  • 출발의 기준을 i (1<=i<=N)로 두는 것이 아니라, 출발을 X로 둬서, X → i 와 X ← i 라고 생각한다.
  • 위 방법을 사용하기 위해서 인접 리스트를 2개 선언하여, 원래 방향과 반대 방향을 저장한다.
  • 각 인접 리스트에 대해 다익스트라 알고리즘을 돌리고, 이동 거리를 dist 배열에 저장한다.
  • 정답은 dist[i][0] + dist[i][1] 중에서, 가장 큰 값이다.




C++ 소스코드


#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;

struct town {
    int road, cost;
    bool operator < (const town t) const { return cost > t.cost; }
};

int n, m, x;
const int INF = 1e9;

void dijkstra(vector<town> v[], int dist[][2], int direct) {
    priority_queue<town> pq;
    pq.push({x-1, 0});
    dist[x-1][direct] = 0;
    while (!pq.empty()) {
        int now = pq.top().road, cost = pq.top().cost;
        pq.pop();
        if (dist[now][direct] < cost) continue;
        for (auto k : v[now]) {
            int next = k.road, ncost = cost+k.cost;
            if (dist[next][direct] > ncost) {
                dist[next][direct] = ncost;
                pq.push({next, ncost});
            }
        }
    }
}

int main() {
    ios_base::sync_with_stdio(false); cin.tie(NULL);
    cin >> n >> m >> x;
    vector<town> a[n], b[n];
    int dist[n][2];
    while (m--) {
        int u, v, w;
        cin >> u >> v >> w;
        a[u-1].push_back({v-1, w});
        b[v-1].push_back({u-1, w});
    }
    fill(&dist[0][0], &dist[n][0], INF);
    dijkstra(a, dist, 0);
    dijkstra(b, dist, 1);
    int ans = 0;
    for (int i=0; i<n; i++) {
        int temp = dist[i][0] + dist[i][1];
        if (ans < temp) ans = temp;
    }
    cout << ans << '\n';
    return 0;
}


✓ fill 함수는 보통 1차원 배열(또는 벡터)을 초기화할 때 이용하지만, 배열의 주소를 이용하면 2차원 배열도 초기화할 수 있다.




Python 3 소스코드


from heapq import heappush, heappop
from sys import stdin
input = stdin.readline

INF = 1e9
n, m, x = map(int, input().split())
dist = [[INF]*2 for _ in range(n)]
a = [[] for _ in range(n)]
b = [[] for _ in range(n)]
for i in range(m):
    u, v, w = map(int, input().split())
    a[u-1].append([v-1, w])
    b[v-1].append([u-1, w])

def dijkstra(k, direct):
    pq = []
    heappush(pq, (0, x-1))
    dist[x-1][direct] = 0
    while pq:
        cost, now = heappop(pq)
        if dist[now][direct] < cost:
            continue
        for nxt, ncost in k[now]:
            ncost += cost
            if dist[nxt][direct] > ncost:
                dist[nxt][direct] = ncost
                heappush(pq, (ncost, nxt))

dijkstra(a, 0)
dijkstra(b, 1)
ans = 0
for i in range(n):
    ans = max(ans, sum(dist[i]))
print(ans)




참고



반응형