๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ
๋ฐฑ์ค€/Platinum

[BOJ] 5719 : ๊ฑฐ์˜ ์ตœ๋‹จ ๊ฒฝ๋กœ

by Jaeguk 2022. 1. 27.
๋ฌธ์ œ ๋งํฌ

5719๋ฒˆ: ๊ฑฐ์˜ ์ตœ๋‹จ ๊ฒฝ๋กœ (acmicpc.net)

 

5719๋ฒˆ: ๊ฑฐ์˜ ์ตœ๋‹จ ๊ฒฝ๋กœ

์ž…๋ ฅ์€ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋กœ ์ด๋ฃจ์–ด์ ธ ์žˆ๋‹ค. ๊ฐ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค์˜ ์ฒซ์งธ ์ค„์—๋Š” ์žฅ์†Œ์˜ ์ˆ˜ N (2 ≤ N ≤ 500)๊ณผ ๋„๋กœ์˜ ์ˆ˜ M (1 ≤ M ≤ 104)๊ฐ€ ์ฃผ์–ด์ง„๋‹ค. ์žฅ์†Œ๋Š” 0๋ถ€ํ„ฐ N-1๋ฒˆ๊นŒ์ง€ ๋ฒˆํ˜ธ๊ฐ€ ๋งค๊ฒจ์ ธ ์žˆ

www.acmicpc.net

ํ’€์ด

์ตœ๋‹จ๊ฒฝ๋กœ๋กœ ํ†ตํ•˜๋Š” ๊ธธ์„ ๋ชจ๋‘ ์ œ์™ธํ•œ ๋‚˜๋จธ์ง€ ๊ฒฝ๋กœ ์ค‘์—์„œ ๊ฐˆ ์ˆ˜ ์žˆ๋Š” ์ตœ๋‹จ๊ฒฝ๋กœ๋ฅผ ๊ตฌํ•˜๋Š” ๋ฌธ์ œ.

1. ์ตœ๋‹จ๊ฒฝ๋กœ์— ํฌํ•จ๋˜๋Š” ์ •์ ์„ ์ œ๊ฑฐํ•˜๋ฉด ๊ธธ์ด ์žˆ์–ด๋„ ๋ชป๊ฐ€๊ธฐ ๋•Œ๋ฌธ์— ์•ˆ๋จ

2. ์ตœ๋‹จ๊ฒฝ๋กœ๋ฅผ ํƒ์ƒ‰ํ•˜๊ณ  ๋„๋กœ๋ฅผ ๋ฐ”๋กœ ์ œ๊ฑฐํ•˜๋ฉด ๋งŒ์•ฝ ์ตœ๋‹จ๊ฒฝ๋กœ๊ฐ€ ์—ฌ๋Ÿฌ๊ฐœ์ด๋ฉด์„œ ์ตœ๋‹จ๊ฒฝ๋กœ๋ผ๋ฆฌ

๊ฐ™์€ ๋„๋กœ๋ฅผ ๊ณต์œ ํ•œ๋‹ค๋ฉด?? ๋‘๋ฒˆ์งธ ์ตœ๋‹จ๊ฒฝ๋กœ๋Š” ํƒ์ƒ‰ํ•  ์ˆ˜ ์—†๋‹ค.

 

=> ๊ทธ๋ž˜์„œ ๋‚ด๊ฐ€ ๋– ์˜ฌ๋ฆฐ ์•„์ด๋””์–ด๋Š” ํƒ์ƒ‰ํ•œ ์ตœ๋‹จ๊ฒฝ๋กœ์— ํฌํ•จ๋œ ํ•œ ์ •์ ์„ ๊ธฐ์ค€์œผ๋กœ  ๋“ค์–ด์˜ค๋Š” ๊ฒฝ๋กœ๊ฐ€

์—ฌ๋Ÿฌ๊ฐœ(๋‘ ๊ฐœ ์ด์ƒ)๊ณ  ๋‹ค๋ฅธ ์ •์ ์œผ๋กœ ํ†ตํ•˜๋Š” ๊ฒฝ๋กœ๋„ ์—ฌ๋Ÿฌ๊ฐœ๋ผ๋ฉด?

๊ทธ๋•Œ๋Š”  ๊ทธ ์ •์ ์— ์—ฐ๊ฒฐ๋œ ๋„๋กœ ์ค‘ ์ตœ๋‹จ๊ฒฝ๋กœ์— ํฌํ•จ๋˜๋Š” ๋„๋กœ๋Š” ์ง€์›Œ๋„ ๋  ๊ฒƒ์ด๋‹ค.

์™œ๋ƒ ์ง€์›Œ๋„ ๋‹ค๋ฅธ ๊ฒฝ๋กœ๋กœ ์ด๋™์ด ๊ฐ€๋Šฅํ•˜๋‹ˆ๊นŒ.

=> ๊ทธ ๋„๋กœ๋Š” ์‹ค์ œ๋กœ ์ง€์šฐ๊ณ  ๋‚˜๋จธ์ง€๋Š” Delete๋ผ๋Š” ๋ฒกํ„ฐ์— ์ €์žฅํ•ด ๋’€๋‹ค๊ฐ€ ๋‚˜์ค‘์— ํ•œ ๋ฒˆ์— ์ง€์šด๋‹ค

๊ทธ๋ฆฌ๊ณ  ๋งŒ์•ฝ ์ตœ๋‹จ๊ฒฝ๋กœ์— ํฌํ•จ๋œ ์ •์  ์ค‘ ๊ทธ๋Ÿฌํ•œ ์ •์ ์ด ์—†๋‹ค๋ฉด? ์•„๋ฌด ๋„๋กœ๋‚˜ ์ง€์›Œ๋„ ๋  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค

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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cstdio>
#include <string.h>
#include <string>
#include <stack>
#include <vector>
#include <queue>
#include <climits>
#include <algorithm>
using namespace std;
const int MAX_N = 500 + 5;
typedef priority_queue <pair<pair<int,int>,pair<intint>> , vector<pair<pair<int,int>pair<intint>>>, greater<pair<pair<int,int>pair<intint>>> > Priority_queue;
int N, M;
int S, D;
const int INF = INT_MAX;
vector<int> dist(MAX_N, INF);
vector<pair<int,int>> Before(MAX_N,{-1,-1});
vector<pair<pair<int,int>,bool>> Edge[MAX_N];
vector<pair<intint>> Delete;
 
void dijkstra(int st, int ed) {
    Priority_queue pq;
    pq.push({ { 0, st },{st,st} }); //{๋น„์šฉ, ๋‹ค์Œ ์ •์ },{์ด์ „ ๋„๋กœ์˜ ์ขŒํ‘œ}
    while (!pq.empty()) {
        int now = pq.top().first.second;
        int cost = pq.top().first.first;
        int edge_y = pq.top().second.first;
        int edge_x = pq.top().second.second;
        pq.pop();
        if (dist[now] != INF)
            continue;
        else {
            dist[now] = cost;
            Before[now] = { edge_y, edge_x };
        }
        if (now == ed)
            break;
        for (int i = 0; i < Edge[now].size(); i++) {
            if (Edge[now][i].second) {
                int next = Edge[now][i].first.first;
                int acost = cost + Edge[now][i].first.second;
                if (dist[next] != INF)
                    continue;
                else {
                    pq.push({ {acost,next },{now,i}});//์ด์ „ ๋„๋กœ์˜ ์ •๋ณด๋ฅผ pq์— ๋„ฃ์–ด์คŒ{now,i}๋กœ
                }
            }
        }
    }
}
int main(void)
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    while (true) {
        cin >> N >> M;
        if (!&& !M) break;
        cin >> S >> D;
        int Min_distance = MAX_N;
        for (int i = 0; i < N; i++) {
            Edge[i].clear();
        }
        for (int i = 0; i <= N; i++) {
            Before[i].first = -1;
            Before[i].second = -1;
        }
        Delete.clear();
        fill(dist.begin(), dist.end(), INF);
        for (int i = 0; i < M; i++) {
            int u, v, p;
            cin >> u >> v >> p;
            Edge[u].push_back({ { v,p },true });
        }
        dijkstra(S, D); //์ผ๋‹จ ์ตœ๋‹จ๊ฒฝ๋กœ๋ฅผ ์ฐพ๋Š”๋‹ค
        if (dist[D] == INF) { //๋งŒ์•ฝ ๋ชฉ์ ์ง€์— ๊ฐˆ ์ˆ˜ ์—†์œผ๋ฉด ๋ฐ”๋กœ ์ข…๋ฃŒ
            cout << "-1\n";
            continue;
        }
        else Min_distance = dist[D];
 
        int now_node = D;
        int is_Deleted = false;
        while (true) {
            /* ๊ณผ๊ฑฐ๋ฅผ ์ถ”์ ํ•˜๋ฉด์„œ ๊ฑฐ์ณ์˜จ ๋„๋กœ๋ฅผ Delete๋ผ๋Š” Vector์— ๋„ฃ์–ด์คŒ
            * ๋‚˜์ค‘์— ํ•œ ๋ฒˆ์— ๋„๋กœ๋ฅผ ์‚ญ์ œํ•˜๋ ค๋Š” ๋ชฉ์ 
            * ๋งŒ์•ฝ ๊ทธ ์ •์ ๊นŒ์ง€ ๋„๋‹ฌํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ๋กœ๊ฐ€ ์—ฌ๋Ÿฌ๊ฐœ๊ณ  ๊ทธ ์ •์ ์—์„œ ๊ฐˆ ์ˆ˜ ์žˆ๋Š” ์ •์ ์ด ์—ฌ๋Ÿฌ๊ฐœ๋ฉด
            * ๊ทธ ๋„๋กœ๋Š” ์ผ๋‹จ ํ•˜๋‚˜ ์‚ญ์ œํ•จ
            */
            int Before_y = Before[now_node].first;
            int Before_x = Before[now_node].second;
            if (Before_y == -1)
                break;
            else if (Before_y == S) {
                if (!is_Deleted && Edge[Before_y].size() != 1) {
                    if (Edge[now_node].size() != 1) {
                        Edge[Before_y][Before_x].second = false;
                        is_Deleted = true;
                    }
                }
                Delete.push_back({ Before_y, Before_x });
                break;
            }
            else {
                if (!is_Deleted && Edge[Before_y].size() != 1) {
                    if (Edge[now_node].size() != 1) {
                        Edge[Before_y][Before_x].second = false;
                        is_Deleted = true;
                    }
                }
                Delete.push_back({ Before_y, Before_x });
                now_node = Before_y;
            }
        }
        if (!is_Deleted) {
            Edge[Before[D].first][Before[D].second].second = false;
        }
        while (true) {
            is_Deleted = false;
            for (int i = 0; i <= N; i++) {
                Before[i].first = -1;
                Before[i].second = -1;
            }
            fill(dist.begin(), dist.end(), INF);
            dijkstra(S, D);
            //๋ฐ˜๋ณต๋ฌธ์„ ๋Œ๋ฉด์„œ ์ตœ๋‹จ๊ฒฝ๋กœ์™€ ๊ฐ™์€ ๊ธธ์ด์˜ ๊ฒฝ๋กœ๊ฐ€ ๋˜์žˆ๋Š”์ง€ ๊ณ„์† ํƒ์ƒ‰
            //์žˆ์œผ๋ฉด ๊ทธ ๊ฒฝ๋กœ๋Š” ๋˜ Delte ๋ฒกํ„ฐ์— ์ €์žฅ
            if (dist[D] != INF && Min_distance == dist[D]) {
                now_node = D;
                while (true) {
                    int Before_y = Before[now_node].first;
                    int Before_x = Before[now_node].second;
                    if (Before_y == -1)
                        break;
                    else if (Before_y == S) {
                        if (!is_Deleted && Edge[Before_y].size() != 1) {
                            if (Edge[now_node].size() != 1) {
                                Edge[Before_y][Before_x].second = false;
                                is_Deleted = true;
                            }
                        }
                        Delete.push_back({ Before_y, Before_x });
                        break;
                    }
                    else {
                        if (!is_Deleted && Edge[Before_y].size() != 1) {
                            if (Edge[now_node].size() != 1) {
                                Edge[Before_y][Before_x].second = false;
                                is_Deleted = true;
                            }
                        }
                        Delete.push_back({ Before_y, Before_x });
                        now_node = Before_y;
                    }
                }
                if (!is_Deleted) {
                    Edge[Before[D].first][Before[D].second].second = false;
                }
 
            }
            else break;
        }
        if (dist[D] == INF) {
            cout << "-1\n";
            continue;
        }
        for (int i = 0; i < Delete.size(); i++) {
            int Delete_y = Delete[i].first;
            int Delete_x = Delete[i].second;
            Edge[Delete_y][Delete_x].second = false;
        }
        fill(dist.begin(), dist.end(), INF);
        dijkstra(S, D);
        if (dist[D] == INF)
            cout << "-1\n";
        else cout << dist[D] << "\n";
    }
    return 0;
}
cs

์ฝ”๋“œ๊ฐ€ ์กฐ๊ธˆ ๋ณต์žกํ•œ๋ฐ, ๋จผ์ € ๋งจ ์ฒ˜์Œ ๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ํ†ตํ•ด ์ตœ๋‹จ๊ฒฝ๋กœ๋ฅผ ํƒ์ƒ‰ํ•˜๊ณ  ๊ทธ ๊ฒฝ๋กœ์˜ ๊ฐ€์ค‘์น˜ ํ•ฉ์„ Min์ด๋ผ๋Š” ๋ณ€์ˆ˜์— ์ €์žฅํ•ด๋’€๋‹ค. ์ตœ๋‹จ๊ฒฝ๋กœ์— ํฌํ•จ๋œ ๋„๋กœ ์ค‘ ์•„๊นŒ ๋งํ•œ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋Š” ๋„๋กœ๋Š” ์‹ค์ œ๋กœ ๊ฐ’์„ false๋กœ ๋ฐ”๊ฟ” ์ง€์›Œ์ฃผ๊ณ  ๋‚˜๋จธ์ง€ ๋„๋กœ๋Š” Delete๋ผ๋Š” ๋ฒกํ„ฐ์— ์ €์žฅํ•ด๋’€๋‹ค.

๋‹ค์‹œ ๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‹คํ–‰ํ–ˆ์„ ๋•Œ ์•„๊นŒ ์ €์žฅํ•ด๋‘” Min๊ฐ’๊ณผ ๊ฐ€์ค‘์น˜์˜ ํ•ฉ์ด ๊ฐ™์€ ๊ฒฝ๋กœ๊ฐ€ ์•„์ง ์กด์žฌํ•œ๋‹ค๋ฉด ๊ทธ ๊ฒฝ๋กœ๋„ ์ง€์›Œ์•ผํ•œ๋‹ค. => ์ด ๊ณผ์ •์„ ๊ณ„์† ๋ฐ˜๋ณต. Min๊ณผ ๊ฐ’์ด ๊ฐ™์€ ๊ฒฝ๋กœ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š์„ ๋•Œ ๊นŒ์ง€.

์ตœ๋‹จ๊ฒฝ๋กœ๊ฐ€ ๋” ์ด์ƒ ์—†๋‹ค๊ณ  ํŒ๋‹จ๋˜๋ฉด ๊ทธ ๋•Œ Delte ๋ฒกํ„ฐ์— ์ €์žฅ๋˜์–ด ์žˆ๋˜ ๋„๋กœ๋ฅผ ๋ชจ๋‘ false๋กœ ๋ฐ”๊ฟ” ๋„๋กœ๋ฅผ ์ง€์šด๋‹ค.

๊ทธ ํ›„ ๋‹ค์ต์ŠคํŠธ๋ผ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ํ•œ ๋ฒˆ ๋” ๋Œ๋ ค์„œ ๋‚˜์˜จ ๊ฐ’์ด INF๋ผ๋ฉด -1์ถœ๋ ฅ ์•„๋‹ˆ๋ฉด ํ•ด๋‹น๊ฐ’ ์ถœ๋ ฅ

728x90