반응형

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] == 1continue;
        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
반응형

+ Recent posts