1 분 소요

최소비용 구하기 2 (백준 Gold 3)

https://www.acmicpc.net/problem/11779

n개의 도시에서 단반향 버스 노선이 m개 주어질때
시작 도시 에서 목표 도시까지 가는
최소 비용과 그 경우의 방문 도시의 개수 와 경로를 출력하는 문제

풀이 방법

최단 비용 거리를 구하는 동시에
개수와 경로가 필요한 문제이다

  • 비용이 존재하기에 일반적인 BFS로는 풀 수 없음
    (목적지가 바로 가는 버스가 있다면 비용을 고려하지 않으므로)

  • 다익스트라 알고리즘을 사용
    (Priority_queue)

  • 최소 비용을 기준으로 맵을 순회하며
    경로 값을 갱신
    (시작 비용은 0)

  • 다만 ‘경로’ 또한 계산해야 하므로
    visit를 pair<int,int>로 체크하여
    이전 방문 위치를 기록한 후
    마지막에 vector 에 모아 거꾸로 출력하였다

제출 코드

#include<iostream>
#include<vector>
#include<queue>
#include<unordered_map>
#include<limits.h>

using namespace std;

int n, m;
int start, target;

struct infos
{
	int now;
	int nowCount;
	int nowCost;
};

struct Compare
{
	bool operator()(const infos& a, const infos& b)
	{
		return a.nowCost > b.nowCost;
	}
};

void func(unordered_map<int, vector<pair<int, int>>>& umaps)
{
	// 이전에 방문한 노드와 그 비용
	// 이걸 통해 역추적할 예정
	vector<pair<int, int>> visit(n + 1);

	for (auto& p : visit)
	{
		p.first = 0;
		p.second = INT_MAX;
	}

	visit[start] = { start,0 };

	priority_queue<infos, vector<infos>, Compare> pq;
	pq.push({ start,1,0 });

	int aCost = 0;
	int aCount = 0;

	while (pq.empty() == false)
	{
		int now = pq.top().now;
		int nowCount = pq.top().nowCount;
		int nowCost = pq.top().nowCost;
		pq.pop();

		if (now == target)
		{
			aCost = nowCost;
			aCount = nowCount;
			break;
		}

		if (umaps.find(now) == umaps.end())
			continue;

		for (auto& p : umaps[now])
		{
			int next = p.first;
			int nCost = p.second;

			if (visit[next].second <= nowCost + nCost)
				continue;

			visit[next].first = now;
			visit[next].second = nowCost + nCost;

			pq.push({ p.first,nowCount + 1, nowCost + p.second });
		}
	}

	cout << aCost << '\n';
	cout << aCount << '\n';

	vector<int> v;
	int idx = target;
	for (int i = 0; i < aCount; i++)
	{
		v.push_back(idx);
		idx = visit[idx].first;
	}

	for (auto i = v.rbegin(); i != v.rend(); i++)
		cout << *i << ' ';

}

int main()
{
	cin.tie(nullptr);
	ios::sync_with_stdio(false);

	cin >> n >> m;

	unordered_map<int, vector<pair<int, int>>> umaps;
	umaps.reserve(n);

	for (int i = 0; i < m; i++)
	{
		int s, t, c;
		cin >> s >> t >> c;
		umaps[s].push_back({ t,c });
	}

	cin >> start >> target;

	func(umaps);

	return 0;
}

결과

Image

수많은 메모리 초과의 경우
왜 그럴까… 싶었는데

if (visit[next].second < nowCost + nCost)
				continue;

조건문을 이렇게 작성하여
같은 비용인 경우도 다시 Pq에 넣었기에
발생한 문제…
<= 로 고쳐주니 통과하였다

댓글남기기