본문 바로가기
Develop/백준 (Cpp)

[백준] 21940번 : 가운데에서 만나기 (C++)

by Tarra 2023. 10. 23.

21940번 : 가운데에서 만나기


문제)

준형이는 내일 친구들을 만나기로 했다. 준형이와 친구들은 서로 다른 도시에 살고 있다.
도시를 연결하는 도로는 일방 통행만 있어서 도시 Ai에서 도시 Bi로 가는 시간과 도시 Bi에서 도시 Ai로 가는 시간이 다를 수 있다.
준형이와 친구들은 아래 조건을 만족하는 도시 X를 선택하여 거기서 만나려고 한다.

  • 왕복시간은 자신이 살고 있는 도시에서 도시 X로 이동하는 시간과 도시 X에서 다시 자신이 살고 있는 도시로 이동하는 시간을 합한 것이다.
  • 준형이와 친구들이 도로를 이용하여 갈 수 있는 도시만 선택한다.
  • 준형이와 친구들의 왕복시간 들 중 최대가 최소가 되는 도시 X를 선택한다.
  • 준형이와 친구들이 이동할 수 있는 도시가 최소한 하나 이상이 있음을 보장한다.

도시가 많다보니 계산하기 힘들다. 준형이와 친구들을 대신하여 도시 X를 알려주자.

 

 

 

입력 :

첫 번째 줄에는 도시의 개수 N과 도로의 개수 M이 주어진다.
두 번째 줄부터 M + 1줄까지 도시 Ai, 도시 Bi, 도시 Ai에서 도시 Bi로 이동하는데 걸리는 시간 Ti가 공백으로 구분되어 주어진다.
M + 2줄에는 준형이와 친구들의 총 인원 K가 주어진다.
M + 3줄에는 준형이와 친구들이 살고 있는 도시의 번호 Ci가 공백으로 구분되어 주어진다.

 

 

 

출력 :

위 조건을 만족하는 도시 X의 번호를 출력한다. 만약 가능한 도시 X가 여러 개인 경우는 도시의 번호를 오름차순으로 출력한다.

 

 

 

 

 

풀이)

dist를 처음부터 2차원 배열로 선언해놓고 사용했어야 시간초과가 안났을텐데

vector를 이용해서 쓸때마다 초기화를 했더니 시간초과가 나서 푸는데 오래 걸렸다.

 

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
// 21940. 가운데에서 만나기
#include <iostream>
#include <vector>
#include <queue>
#include <map>
#include <climits>
 
using namespace std;
 
int n, m, k;
vector<vector<pair<intint>>> vec;
vector<int> _friend;
vector<long long> city;
 
// dist를 2차원 배열로 미리 만들어둔다.
long long dist[201][201];
 
priority_queue<pair<long longint>
    , vector<pair<long longint>>
    , greater<pair<long longint>>> pq;
 
long long dijkstra(int s, int e)
{
    while (!pq.empty()) pq.pop();
 
    dist[s][s] = 0;
    pq.push(make_pair(0, s));
 
    while (!pq.empty())
    {
        long long d = pq.top().first;
        int cur = pq.top().second;
        pq.pop();
 
        if (dist[s][cur] < d) continue;
 
        for (int i = 0; i < vec[cur].size(); i++)
        {
            long long nd = d + vec[cur][i].second;
            int nxt = vec[cur][i].first;
 
            if (dist[s][nxt] > nd)
            {
                dist[s][nxt] = nd;
                pq.push(make_pair(nd, nxt));
            }
        }
    }
 
    // 갈 수 없는 경우
    if (dist[s][e] == LONG_MAX) return 0;
    return dist[s][e];
}
 
int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(0);
 
    cin >> n >> m;
    fill(&dist[0][0], &dist[200][201], LONG_MAX);
    vec.resize(n + 1vector<pair<intint>>());
 
    int a, b;
    int c;
    for (int i = 0; i < m; i++)
    {
        cin >> a >> b >> c;
        // 도시 a에서 b까지 가는 시간 c
        vec[a].push_back(make_pair(b, c));
    }
 
    cin >> k;
    for (int i = 0; i < k; i++)
    {
        cin >> a;
        _friend.push_back(a);
    }
 
    city.resize(n + 10);
 
    long long _min = LONG_MAX;
 
    // 모든 도시에 대해
    for (int i = 1; i < n + 1; i++)
    {
        for (int j = 0; j < k; j++)
        {
            // 기존 city[i]값과 j번째 친구가 해당 도시에 갔다온 값중
            // 최댓값을 저장한다.
            city[i] = max(city[i]
                , dijkstra(i, _friend[j]) + dijkstra(_friend[j], i));
        }
 
        // 각 도시의 최댓값 중 최소가 되는 도시 X를 저장한다.
        _min = min(city[i], _min);
    }
 
    // 도시들 중 최대가 최소가 되는 도시 X를 출력한다.
    for (int i = 1; i < n + 1; i++)
    {
        if(city[i] == _min)
        {
            cout << i << " ";
        }
    }
 
    return 0;
}
 
cs

출처 : https://www.acmicpc.net/problem/21940 

 

21940번: 가운데에서 만나기

위 조건을 만족하는 도시 $X$의 번호를 출력한다. 만약 가능한 도시 $X$가 여러 개인 경우는 도시의 번호를 오름차순으로 출력한다.

www.acmicpc.net