문제링크 : https://www.acmicpc.net/problem/14938
14938번: 서강그라운드
예은이는 요즘 가장 인기가 있는 게임 서강그라운드를 즐기고 있다. 서강그라운드는 여러 지역중 하나의 지역에 낙하산을 타고 낙하하여, 그 지역에 떨어져 있는 아이템들을 이용해 서바이벌을
www.acmicpc.net
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
const int MAX = 987654321;
int N, M, R, result;
vector<pii>v[101];
int arr[101];
int dist[101];
priority_queue<pii,vector<pii>,greater<pii>> pq;
void dijkstra(int s)
{
for(int i=0; i<N; i++) dist[i]=MAX;
dist[s] = 0;
pq.push({0, s});
while(!pq.empty()) //거리값 저장
{
auto[cost, cur] = pq.top();
pq.pop();
for(int i=0; i<v[cur].size(); i++)
{
auto[next, ncost] = v[cur][i];
if(cost + ncost >= dist[next]) continue;
dist[next] = cost + ncost;
pq.push({dist[next], next});
}
}
int sum = 0;
for(int i=0; i<N; i++) //가능한 거리에 대한 최대 값 저장
{
if(dist[i] > M) continue;
sum += arr[i];
}
result = max(result, sum);
}
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
cin >> N >> M >> R;
for(int i=0; i<N; i++)
{
cin >> arr[i];
}
for(int i=0; i<R; i++)
{
int a, b, c;
cin >> a >> b >> c;
v[a-1].push_back({b-1, c}); //양방향 통행
v[b-1].push_back({a-1, c});
}
for(int i=0; i<N; i++)
{
dijkstra(i); //모든 정점에서 탐색
}
cout << result;
return 0;
}
플로이드-워셜 또는 데이크스트라로 풀리는 문제이다.
나는 데이크스트라가더 익숙해서 데이크스트라로 풀었다.
기본 데이크스트라에 추가적으로 거리에 대한 최대값을 저장해야 한다.
따라서 모든 정점에 대하여 데이크스트라를 돌려주고, 각 정점을 기준으로 거리를 구했을 때 가능한 거리인 M까지 얻을 수 있는 아이템의 갯수를 더해준다.
이렇게 구한 아이템의 갯수가 최대일 때를 따로 저장하여 출력해주면 된다.
해당 문제를 풀 때 번호가 0번이 아닌 1번부터 시작한다는 것을 고려하지 않아서 여러번 틀렸다.
별 생각없이 i=0부터 해서 아이템 배열을 채워나갔는데, 간선에 대한 값을 저장할 때는 0부터가 아니라 1부터를 기준으로 입력받는다.
따라서 간선인 a, b를 시작값인 0에 맞춰서 1씩 빼주거나, 앞에서 입력받고 나머지 탐색에 대해서도 i=1부터 시작하도록 해주어야 한다.
그리고 모든 정점에 대해서 데이크스트라를 돌려주는 것이기 때문에 매 탐색마다 초기화해주는 것도 잊으면 안된다.
'백준 > 골드' 카테고리의 다른 글
[백준 2206번] 벽 부수고 이동하기 (C++) (0) | 2023.08.10 |
---|---|
[백준 11444번] 피보나치 수 6 (C++) (0) | 2023.08.09 |
[백준 2448번] 별 찍기 - 11 (C++) (0) | 2023.08.07 |
[백준 1167번] 트리의 지름 (C++) (0) | 2023.08.05 |
[백준 1967번] 트리의 지름 (C++) (0) | 2023.08.05 |