https://www.acmicpc.net/problem/11900
11900번: 차이 그래프
첫 번째 줄에 그래프 G의 정점의 수 N (5≤N≤2,000)이 주어집니다. 두 번째 줄에 A[1],A[2],⋯,A[N−1] (0≤A[1],A[2],⋯,A[N−1]≤10,000)이 공백을 사이로 두고 주어집니다. 세 번째 줄에 질의의 수 Q (1≤Q≤20
www.acmicpc.net
풀이
0. 문제를풀기 앞서서 풀어야되는 문제
https://www.acmicpc.net/problem/1753
1753번: 최단경로
첫째 줄에 정점의 개수 V와 간선의 개수 E가 주어진다. (1 ≤ V ≤ 20,000, 1 ≤ E ≤ 300,000) 모든 정점에는 1부터 V까지 번호가 매겨져 있다고 가정한다. 둘째 줄에는 시작 정점의 번호 K(1 ≤ K ≤ V)가
www.acmicpc.net
다익스트라 알고리즘을 사용하는 문제입니다. 다익스트라를 공부하고 오세요.
1. 핵심 아이디어
u → v로 가는 간선이 존재하면 (u+1)%N → (v+1)%N으로 가는 간선도 존재합니다!!
위의 사실을 토대로 생각해보면
a → b → c의 과정을 통해서 a → c로 이동하는 경로가 존재한다면
(a+1)%N → (b+1)%N → (c+1)%N를 통해서 (a+1)%N → (c+1)%N로 이동하는 경로 또한
존재한다는 것을 확인할 수 있고 두 경로의 길이는 같을 것 입니다.
위의 아이디어를 통해서 이해하기 편한 한 가지 예시를 들자면
(N = 5)
1 → 0로 가는 경로는 0 → 4로 표현될 수 있습니다.
((1 + 4)%N = 0), ((0 + 4)%N = 4)
한 번의 다익스트라만으로 해당 문제를 풀 수 있습니다.
코드
#include <bits/stdc++.h>
#pragma warning(disable:4996)
using namespace std;
#define endl "\n"
#define int long long
#define float long double
const int INF = 999999999999999;
const int Dic[4][2] = { {0,1},{0,-1},{1,0},{-1,0} };
////////////////////////////////////////////////////////////////////////
const int MAX = 2003;
int Dist[MAX];
int N, Q;
int A[MAX];
//다익스트라
void Dijkstra()
{
//초기화
for (int i = 0; i < MAX; i++)
Dist[i] = INF;
priority_queue<pair<int, int>> pq;
Dist[0] = 0;
pq.push({ 0,0 });
while (!pq.empty())
{
int cost = -pq.top().first;
int u = pq.top().second;
pq.pop();
if (Dist[u] < cost)
continue;
for (int v = 0; v <= N - 1; v++)
{
if (u == v)
{
//같은 노드는 넘어간다.
continue;
}
if (u - v >= 1)
{
//u가 v보다 클 경우 처리
int AV = A[u - v];
if (AV == 0)
{
//간선이 없는 경우 넘어간다.
continue;
}
int nextDis = cost + AV;
if (Dist[v] > nextDis)
{
Dist[v] = nextDis;
pq.push({ -nextDis, v });
}
}
else
{
//u가 v보다 작을 경우 처리
int AV = A[u - v + N];
if (AV == 0)
{
//간선이 없는 경우 넘어간다.
continue;
}
int nextDis = cost + AV;
if (Dist[v] > nextDis)
{
Dist[v] = nextDis;
pq.push({ -nextDis, v });
}
}
}
}
}
int32_t main()
{
ios_base::sync_with_stdio(false);
std::cin.tie(NULL);
std::cout.tie(NULL);
std::cin >> N;
for (int i = 1; i <= N - 1; i++)
std::cin >> A[i];
Dijkstra();
std::cin >> Q;
for (int i = 0; i < Q; i++)
{
int a, b;
std::cin >> a >> b;
int ans = -1;
//nb : a를 0으로 만들었을때의 b의 값
if (a > b)
{
int nb = b + (N - a);
ans = Dist[nb];
}
else
{
int nb = b - a;
ans = Dist[nb];
}
//정답을 출력
std::cout << (ans == INF ? -1 : ans) << endl;
}
}
'알고리즘 > 문제풀이' 카테고리의 다른 글
백준 25606 장마 (1) | 2022.09.23 |
---|---|
백준 8903 장비 (0) | 2022.08.24 |
백준 1006 습격자 초라기 (0) | 2022.04.09 |
백준 1661 다솜이의 신발가게 (0) | 2022.03.30 |
백준 16359 Disks Arrangement (0) | 2021.12.01 |