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

+ Recent posts