https://www.acmicpc.net/problem/1948
1948번: 임계경로
첫째 줄에 도시의 개수 n(1 ≤ n ≤ 10,000)이 주어지고 둘째 줄에는 도로의 개수 m(1 ≤ m ≤ 100,000)이 주어진다. 그리고 셋째 줄부터 m+2줄까지 다음과 같은 도로의 정보가 주어진다. 처음에는 도로의
www.acmicpc.net
[ 문제풀이 ]
이 문제를 풀기 전에 다음 글을 먼저 읽고 오시는 것을 추천드립니다!
https://rudalsd.tistory.com/72
[ 알고리즘 ] 위상 정렬 알고리즘(Topological Sort Algorithm)
1. 위상 정렬 알고리즘(Topological Sort Algorithm)이란? 위상 정렬 알고리즘(Topological Sort Algorithm)은 어떤 일을 하는 순서를 찾는 알고리즘입니다. 만약 먼저 방문해야 하는 노드가 있다면 그 노드를.
rudalsd.tistory.com
먼저 최장 거리를 얻는 방법은 다음과 같습니다.
1. queue에 시작 노드를 넣고 bfs를 시작합니다.
2. 위상 정렬 알고리즘을 이용하여 해당 노드까지 오는 모든 길의 걸리는 시간 중 가장 오래 걸리는 시간을 dist 배열에 저장해줍니다.
3. 현재 노드까지 오는 모든 길을 탐색하였으면 queue에 넣어줍니다.
4. 마지막 노드에 도착했을 때 거리를 return 해주면 최장 거리를 얻을 수 있습니다.
이 최장 거리를 이용하여 오는데 지나온 도로를 찾을 수 있습니다.
마찬가지로 bfs를 통해 (현재 노드까지 오는데 걸리는 거리 - 다음 노드까지의 거리 == 다음 노드까지의 최장 거리) 일 때 그 도로는 최장 거리로 가는 도로에 포함되므로 ret에 1을 더해줍니다.
방문했던 노드에는 다시 방문하면 안 되므로 visited배열을 통해 재방문을 제한해줍니다.
[ 소스 코드 ]
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 | #include<iostream> #include<vector> #include<queue> using namespace std; struct node { int to; int dist; }; int n, m; int from, to; vector<node> list[10001]; vector<node> r_list[10001]; int cnt[10001], dist[10001]; int visited[10001]; int Longest_dist(int from) //가장 오래걸리는 시간 구하기 { queue<node> q; q.push({ from, 0 }); while (!q.empty()) { int cur = q.front().to; int cDist = q.front().dist; q.pop(); if (cur == to) { return cDist; } for (int i = 0; i < list[cur].size(); i++) { int next = list[cur][i].to; int nDist = list[cur][i].dist; cnt[next]--; dist[next] = max(dist[next], cDist + nDist); //다음 노드까지 갈 수 있는 최대 거리 if (cnt[next] == 0) { //다음 노드까지 갈 수 있는 모든 방법으로 갔을 때 q.push({ next,dist[next] }); } } } } int Find_road(int max) //최대 거리로 갈 수 있는 도로 찾기 { int ret = 0; queue<node> q; q.push({ to, max }); while (!q.empty()) { int cur = q.front().to; int cDist = q.front().dist; q.pop(); if (visited[cur] == 1) continue; visited[cur] = 1; for (int i = 0; i < r_list[cur].size(); i++) { int next = r_list[cur][i].to; int nDist = r_list[cur][i].dist; if (cDist - nDist == dist[next]) { ret++; if (visited[next] != 1) { q.push({ next,cDist - nDist }); } } } } return ret; } int main() { cin >> n >> m; for (int i = 0; i < m; i++) { int a, b, c; scanf("%d %d %d", &a, &b, &c); list[a].push_back({ b,c }); r_list[b].push_back({ a,c }); cnt[b]++; } cin >> from >> to; int max = Longest_dist(from); int cnt = Find_road(max); cout << max << endl << cnt; } | cs |
'백준' 카테고리의 다른 글
[ 백준 ] 14938번 - 서강그라운드 (C++) (0) | 2022.07.25 |
---|---|
[ 백준 ] 2150번 - Strongly Connected Component (C++) (0) | 2022.07.24 |
[ 백준 ] 10830번 - 행렬 제곱 (C++) (0) | 2022.07.21 |
[ 백준 ] 1786번 - 찾기 (C++) (0) | 2022.07.20 |
[ 백준 ] 1761번 - 정점들의 거리 (C++) (0) | 2022.07.18 |