๐Ÿ‘ฉ‍๐Ÿ’ป ํ”„๋กœ๊ทธ๋ž˜๋ฐ/๐ŸŽ ์•Œ๊ณ ๋ฆฌ์ฆ˜

๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜(์ตœ๋‹จ ๊ฒฝ๋กœ)

peewoong 2024. 4. 19. 10:31

๐ŸŸฉ์Œ์˜ ๊ฐ€์ค‘์น˜(์Œ์˜ ๊ฐ„์„ , ์Œ์˜ ๊ฐ’)๊ฐ€ ์—†๋Š” ๊ทธ๋ž˜ํ”„์˜ ํ•œ ๋…ธ๋“œ์—์„œ ๊ฐ ๋ชจ๋“  ๋…ธ๋“œ๊นŒ์ง€์˜ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ๋ฅผ ๊ตฌํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜

๋‘ ๊ผญ์ง“์  ๊ฐ„์˜ ๊ฐ€์žฅ ์งง์€ ๊ฒฝ๋กœ๋ฅผ ์ฐพ๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด์ง€๋งŒ

ํ•œ ๊ผญ์ง“์ ์„ "์†Œ์Šค" ๊ผญ์ง“์ ์œผ๋กœ ๊ณ ์ •ํ•˜๊ณ , ๊ทธ๋ž˜ํ”„์˜ ๋‹ค๋ฅธ ๋ชจ๋“  ๊ผญ์ง“์ ๊นŒ์ง€์˜ ์ตœ๋‹จ๊ฒฝ๋กœ๋ฅผ ์ฐพ๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ ์ตœ๋‹จ ๊ฒฝ๋กœ ํŠธ๋ฆฌ๋ฅผ ๋งŒ๋“œ๋Š” ๊ฒƒ์œผ๋กœ๋„ ์‚ฌ์šฉ

 

๐ŸŸฉ ๊ทธ๋ฆฌ๋””์ด์ž ๋™์ ๊ณ„ํš๋ฒ•

๊ทธ๋ฆฌ๋”” : ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ๋…ธ๋“œ ์ค‘์—์„œ ๊ฐ€์žฅ ๋น„์šฉ์ด ์ ์€ ๋…ธ๋“œ๋ฅผ ์„ ํƒ

๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ : ํ•ด๋‹น ๋…ธ๋“œ๋กœ๋ถ€ํ„ฐ ๊ฐˆ ์ˆ˜ ์žˆ๋Š” ๋…ธ๋“œ๋“ค์˜ ๋น„์šฉ์„ ๊ฐฑ์‹ 

๐Ÿ‘‰ ๊ฐ€๋Šฅํ•œ ์ ์€ ๋น„์šฉ์œผ๋กœ ๊ฐ€์žฅ ๋น ๋ฅด๊ฒŒ ํ•ด๋‹ต์„ ๋„๋‹ฌํ•˜๋Š” ๊ฒฝ๋กœ๋ฅผ ์ฐพ์•„๋‚ด๋Š” ๋Œ€๋ถ€๋ถ„์˜ ๋ฌธ์ œ์— ์‘์šฉ๋œ๋‹ค.

 

๐ŸŸฉ ์˜ˆ์ œ

A๋…ธ๋“œ์—์„œ ์ถœ๋ฐœํ•˜์—ฌ F๋…ธ๋“œ๋กœ ๊ฐ€๋Š” ์ตœ๋‹จ๊ฒฝ๋กœ๋ฅผ ๊ตฌํ•˜๋Š” ๋ฌธ์ œ

S = ๋ฐฉ๋ฌธํ•œ ๋…ธ๋“œ๋“ค์˜ ์ง‘ํ•ฉ

d[N] = A -> N๊นŒ์ง€ ๊ณ„์‚ฐ๋œ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ

Q = ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ๋…ธ๋“œ๋“ค์˜ ์ง‘ํ•ฉ

ํ™•์ธ๋˜์ง€ ์•Š์€ ๊ฑฐ๋ฆฌ๋Š” ์ „๋ถ€ ์ดˆ๊ธฐ๊ฐ’์„ ๋ฌดํ•œ์œผ๋กœ ์žก๋Š”๋‹ค ์˜ˆ)INF

 

 

์ถœ๋ฐœ์ง€์™€ ์ถœ๋ฐœ์ง€์˜ ๊ฑฐ๋ฆฌ๋Š” ํ™•์ธํ•ด ๋ณผ ํ•„์š”๋„ ์—†์ด 0 ๐Ÿ‘‰ d[A] = 0

์ถœ๋ฐœ์ง€๋ฅผ ์ œ์™ธํ•œ ๋ชจ๋“  ๋…ธ๋“œ๋“ค๋„ ์•„์ง ํ™•์ธ๋˜์ง€ ์•Š์•˜๊ธฐ์— ๐Ÿ‘‰ d[๋‹ค๋ฅธ ๋…ธ๋“œ] = ๋ฌดํ•œ

Q๋Š” ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š๋Š” ๋…ธ๋“œ๋“ค์˜ ์ง‘ํ•ฉ์ด๋ฏ€๋กœ, ์ดˆ๊ธฐํ™”ํ•  ๋•Œ๋Š” ๋ชจ๋“  ๋…ธ๋“œ๋“ค์˜ ์ง‘ํ•ฉ์ด ๋œ๋‹ค.

S๋Š” ๋ฐฉ๋ฌธํ•œ ๋…ธ๋“œ๊ฐ€ ์•„์ง ์—†์œผ๋ฏ€๋กœ ๊ณต์ง‘ํ•ฉ ์ƒํƒœ

 

1. ๋ฃจํ”„๋ฅผ  ๋Œ๋ ค ์ด์›ƒ ๋…ธ๋“œ๋ฅผ ๋ฐฉ๋ฌธํ•˜๊ณ  ๊ฑฐ๋ฆฌ๋ฅผ ๊ณ„์‚ฐํ•œ๋‹ค.

 

2. ์ฒซ ๋ฃจํ”„ ์ดํ›„์˜ ๊ทธ๋ž˜ํ”„์˜ ์ƒํƒœ๊ฐ€ ์—…๋ฐ์ดํŠธ๋˜๋Š” ๋ฐฉ์‹

 

3. ๋” ๋น ๋ฅธ ๊ฒฝ๋กœ๋ฅผ ๋ฐœ๊ฒฌํ•œ ๊ฒฝ์šฐ, d[C] = 5 -> 4 ๊ฐ’ ์—…๋ฐ์ดํŠธ

 

4. ๋ฌดํ•œ๋ฐ˜๋ณต ๋ฐ ๊ฒฐ๊ณผ

๋ชฉ์ ์ง€๊ฐ€ F์˜€์œผ๋ฏ€๋กœ, ๊ฑฐ๋ฆฌ๋Š” 8

 

๐ŸŸฉ ๊ตฌํ˜„ ๋ฐฉ๋ฒ•

1. ์ธ์ ‘ ํ–‰๋ ฌ, ์„ ํ˜•ํƒ์ƒ‰(๋ฐ˜๋ณต๋ฌธ ์ด์šฉ), O(V^2)

ํ•œ ๋ฒˆ ๋ฐฉ๋ฌธํ•œ ๋ฐฐ์—ด์€ ๋ฐฉ๋ฌธํ•  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ ๋ฐฉ๋ฌธ ์—ฌ๋ถ€๋ฅผ ์ฒดํฌํ•  ๋ฐฐ์—ด์ด ํ•„์š”ํ•  ๊ฒƒ์ด๊ณ , ๊ฐ ๋…ธ๋“œ๊นŒ์ง€์˜ ์ตœ์†Œ ๋น„์šฉ์„ ์ €์žฅํ•  ๋ฐฐ์—ด์ด ํ•„์š”ํ•  ๊ฒƒ

๊ตฌํ˜„์—์„œ ๊ณ ๋ คํ•  ๊ฒƒ์€ ๋ฏธ๋ฐฉ๋ฌธ ์ง€์ ์˜ ๊ฐ’์„ ํ•ญ์ƒ ์ตœ์†Œ์˜ ๊ฐ’์œผ๋กœ ๊ฐฑ์‹ ํ•˜๋Š” ๊ฒƒ์ด ๋ชฉํ‘œ์ด๊ธฐ ๋•Œ๋ฌธ์—, ๋ฏธ๋ฐฉ๋ฌธ์ง€์ ์€ ๋งค์šฐ ํฐ ๊ฐ’์œผ๋กœ ์ดˆ๊ธฐํ™”ํ•˜์—ฌ ์ฒ˜๋ฆฌํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

์ตœ์†Œ ๋น„์šฉ์„ ๊ฐ–๋Š” ๋…ธ๋“œ๋ฅผ ์„ ํƒํ•˜๋Š” ๊ณผ์ •์€ ์ตœ์•…์˜ ๊ฒฝ์šฐ ๋ชจ๋“  ๋…ธ๋“œ๋ฅผ ํ™•์ธํ•ด์•ผ ํ•˜๊ณ , ์ด๊ฒƒ์€ V๋ฒˆ ๋ฐ˜๋ณตํ•˜๊ธฐ ๋•Œ๋ฌธ์—, O(V^2)์˜ ์‹œ๊ฐ„ ๋ณต์žก๋„๋ฅผ ๊ฐ–๋Š”๋‹ค.

#include <iostream>
#include <vector>
#include <limits>

using namespace std;

const int INF = numeric_limits<int>::max(); // ๋ฌดํ•œ๋Œ€๋ฅผ ํ‘œํ˜„ํ•˜๊ธฐ ์œ„ํ•œ ์ƒ์ˆ˜

// ์ตœ์†Œ๊ฐ’ ๋ฐ˜ํ™˜ ํ•จ์ˆ˜
int minDistance(const vector<int>& dist, const vector<bool>& visited) {
    int minDist = INF, minIndex = -1;
    int n = dist.size();

    for (int i = 0; i < n; ++i) {
        if (!visited[i] && dist[i] <= minDist) {
            minDist = dist[i];
            minIndex = i;
        }
    }

    return minIndex;
}

// ๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ํ•จ์ˆ˜
vector<int> dijkstra(const vector<vector<int>>& graph, int start) {
    int n = graph.size();
    vector<int> dist(n, INF); // ์‹œ์ž‘์ ์œผ๋กœ๋ถ€ํ„ฐ์˜ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ๋ฅผ ์ €์žฅํ•  ๋ฐฐ์—ด
    vector<bool> visited(n, false); // ๋ฐฉ๋ฌธ ์—ฌ๋ถ€๋ฅผ ์ €์žฅํ•  ๋ฐฐ์—ด

    dist[start] = 0; // ์‹œ์ž‘์ ๊นŒ์ง€์˜ ๊ฑฐ๋ฆฌ๋Š” 0

    // ๋ชจ๋“  ์ •์ ์„ ๋ฐฉ๋ฌธํ•  ๋•Œ๊นŒ์ง€ ๋ฐ˜๋ณต
    for (int count = 0; count < n - 1; ++count) {
        int u = minDistance(dist, visited); // ์•„์ง ๋ฐฉ๋ฌธํ•˜์ง€ ์•Š์€ ์ •์  ์ค‘ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ๋ฅผ ๊ฐ€์ง„ ์ •์  ์„ ํƒ
        visited[u] = true; // ํ•ด๋‹น ์ •์ ์„ ๋ฐฉ๋ฌธํ–ˆ๋‹ค๊ณ  ํ‘œ์‹œ

        // ์„ ํƒ๋œ ์ •์ ์„ ํ†ตํ•ด ๊ฐˆ ์ˆ˜ ์žˆ๋Š” ๋ชจ๋“  ์ธ์ ‘ ์ •์ ์˜ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ ๊ฐฑ์‹ 
        for (int v = 0; v < n; ++v) {
            if (!visited[v] && graph[u][v] != INF && dist[u] != INF && dist[u] + graph[u][v] < dist[v]) {
                dist[v] = dist[u] + graph[u][v];
            }
        }
    }

    return dist;
}

int main() {
    int n, m; // ๋…ธ๋“œ ์ˆ˜, ๊ฐ„์„  ์ˆ˜
    cin >> n >> m;

    vector<vector<int>> graph(n, vector<int>(n, INF)); // ์ธ์ ‘ ํ–‰๋ ฌ๋กœ ๊ทธ๋ž˜ํ”„ ํ‘œํ˜„

    // ๊ฐ„์„  ์ •๋ณด ์ž…๋ ฅ
    for (int i = 0; i < m; ++i) {
        int u, v, w; // ์ถœ๋ฐœ์ , ๋„์ฐฉ์ , ๊ฐ€์ค‘์น˜
        cin >> u >> v >> w;
        graph[u][v] = w; // u์—์„œ v๋กœ ๊ฐ€๋Š” ๊ฐ€์ค‘์น˜ w์˜ ๊ฐ„์„  ์ถ”๊ฐ€
    }

    int start; // ์‹œ์ž‘์ 
    cin >> start;

    vector<int> shortest_distances = dijkstra(graph, start); // ๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ํ˜ธ์ถœ

    // ์‹œ์ž‘์ ์œผ๋กœ๋ถ€ํ„ฐ ๋ชจ๋“  ์ •์ ๊นŒ์ง€์˜ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ ์ถœ๋ ฅ
    for (int i = 0; i < n; ++i) {
        if (shortest_distances[i] == INF) {
            cout << "INF ";
        } else {
            cout << shortest_distances[i] << " ";
        }
    }
    cout << endl;

    return 0;
}

 

2. ์ธ์ ‘ ๋ฆฌ์ŠคํŠธ์™€ ํž™, ์šฐ์„ ์ˆœ์œ„ ํ ์ด์šฉ, O((V+E)logV)

#include <iostream>
#include <vector>
#include <queue>
#include <limits>

using namespace std;

// ๊ฐ„์„ ์„ ํ‘œํ˜„ํ•˜๋Š” ํด๋ž˜์Šค
class Edge {
public:
    int to;
    int weight;

    Edge(int t, int w) : to(t), weight(w) {}
};

// ์šฐ์„ ์ˆœ์œ„ ํ์—์„œ ์‚ฌ์šฉํ•  ๋น„๊ต ํ•จ์ˆ˜ ์ •์˜
class Compare {
public:
    bool operator() (const pair<int, int>& a, const pair<int, int>& b) {
        return a.second > b.second;
    }
};

// ๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜
vector<int> dijkstra(vector<vector<Edge>>& graph, int start) {
    int n = graph.size();
    vector<int> dist(n, numeric_limits<int>::max()); // ์‹œ์ž‘์ ์—์„œ์˜ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ๋ฅผ ์ €์žฅํ•  ๋ฐฐ์—ด
    dist[start] = 0; // ์‹œ์ž‘์ ๊นŒ์ง€์˜ ๊ฑฐ๋ฆฌ๋Š” 0

    priority_queue<pair<int, int>, vector<pair<int, int>>, Compare> pq; // ์šฐ์„ ์ˆœ์œ„ ํ
    pq.push({start, 0}); // ์‹œ์ž‘์ ๊ณผ ๊ฑฐ๋ฆฌ๋ฅผ ํ์— ์‚ฝ์ž…

    while (!pq.empty()) {
        int u = pq.top().first;
        int d = pq.top().second;
        pq.pop();

        if (d > dist[u]) continue; // ์ด๋ฏธ ์ฒ˜๋ฆฌ๋œ ์ •์ ์€ ์Šคํ‚ต

        for (const Edge& e : graph[u]) {
            int v = e.to;
            int w = e.weight;

            // Relaxation
            if (dist[v] > dist[u] + w) {
                dist[v] = dist[u] + w;
                pq.push({v, dist[v]});
            }
        }
    }

    return dist;
}

int main() {
    int n, m; // ๋…ธ๋“œ ์ˆ˜, ๊ฐ„์„  ์ˆ˜
    cin >> n >> m;

    vector<vector<Edge>> graph(n); // ์ธ์ ‘ ๋ฆฌ์ŠคํŠธ๋กœ ๊ทธ๋ž˜ํ”„ ํ‘œํ˜„

    // ๊ฐ„์„  ์ •๋ณด ์ž…๋ ฅ
    for (int i = 0; i < m; ++i) {
        int u, v, w; // ์ถœ๋ฐœ์ , ๋„์ฐฉ์ , ๊ฐ€์ค‘์น˜
        cin >> u >> v >> w;
        graph[u].push_back(Edge(v, w)); // u์—์„œ v๋กœ ๊ฐ€๋Š” ๊ฐ€์ค‘์น˜ w์˜ ๊ฐ„์„  ์ถ”๊ฐ€
    }

    int start; // ์‹œ์ž‘์ 
    cin >> start;

    vector<int> shortest_distances = dijkstra(graph, start); // ๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ํ˜ธ์ถœ

    // ์‹œ์ž‘์ ์œผ๋กœ๋ถ€ํ„ฐ ๋ชจ๋“  ์ •์ ๊นŒ์ง€์˜ ์ตœ๋‹จ ๊ฑฐ๋ฆฌ ์ถœ๋ ฅ
    for (int i = 0; i < n; ++i) {
        if (shortest_distances[i] == numeric_limits<int>::max()) {
            cout << "INF ";
        } else {
            cout << shortest_distances[i] << " ";
        }
    }
    cout << endl;

    return 0;
}

 

๐ŸŸฉ ์žฅ์ 

์ธ์ ‘ ํ–‰๋ ฌ ๋˜๋Š” ์šฐ์„ ์ˆœ์œ„ ๋Œ€๊ธฐ์—ด์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์–ด ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ๊ฒฝ๋กœ๋ฅผ ํ™•์ธํ•˜๋Š” ๋ฌด์ฐจ๋ณ„ ์ ‘๊ทผ ๋ฐฉ์‹๋ณด๋‹ค ํšจ์œจ์ 

๊ฑฐ๋ฆฌ๋ฟ ์•„๋‹ˆ๋ผ ๊ฒฝ๋กœ๋ฅผ ์ถ”์ ํ•˜๋„๋ก ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‰ฝ๊ฒŒ ์ˆ˜์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

 

๐ŸŸฉ ๋‹จ์ 

์šฐ์„ ์ˆœ์œ„ ๋Œ€๊ธฐ์—ด์„ ์‚ฌ์šฉํ•  ๋•Œ ๊ฐ„์„ ์ด ๋งŽ์€ ๊ทธ๋ž˜ํ”„์˜ ๊ฒฝ์šฐ ๋А๋ ค์งˆ ์ˆ˜ ์žˆ๋‹ค.

๊ทธ๋ž˜ํ”„์™€ ๊ฑฐ๋ฆฌ๋ฅผ ์ €์žฅํ•˜๋ ค๋ฉด ๋งŽ์€ ์–‘์˜ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

๋™์ผํ•œ ๊ฑฐ๋ฆฌ์— ์—ฌ๋Ÿฌ ๊ฒฝ๋กœ๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ ์ตœ์ƒ์˜ ๊ฒฝ๋กœ๋ฅผ ๋ณด์žฅํ•˜์ง€ ์•Š๋Š”๋‹ค.

์ง€ํ˜•์ด๋‚˜ ๊ตํ†ต ์ƒํ™ฉ๊ณผ ๊ฐ™์€ ๋‹ค๋ฅธ ์š”์†Œ๋Š” ๊ณ ๋ คํ•˜์ง€ ์•Š๋Š”๋‹ค.