거의 알고리즘 일기장

백준 11657번 _ 타임머신 본문

알고리즘 문제풀이

백준 11657번 _ 타임머신

건우권 2020. 5. 3. 17:03

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

 

11657번: 타임머신

첫째 줄에 도시의 개수 N (1 ≤ N ≤ 500), 버스 노선의 개수 M (1 ≤ M ≤ 6,000)이 주어진다. 둘째 줄부터 M개의 줄에는 버스 노선의 정보 A, B, C (1 ≤ A, B ≤ N, -10,000 ≤ C ≤ 10,000)가 주어진다. 

www.acmicpc.net

풀이방법

벨만 포드 알고리즘 사용.

음수 사이클 판별은 n번째에와 n-1번을 비교해서 다르면 음수사이클이 있다고 판단.


주의사항

1. 같은 경로로 여러가지 값이 들어올수 있으므로 최솟값만 저장하게 코드를 작성할것.

2. 거리값이 최대 6000*10000 으로 6억까지 들어올수 있으므로 int로 쓰면 오버플로우 될수있음. long long 추천.


전체코드

#include <iostream>
#include <algorithm>
#include <vector>
#include <limits.h>
#include <map>

#define INF 987654321

using namespace std;
map<pair<int, int>, int> tempEdge;
vector<vector<pair<int, long long>>> edge;
long long city[501];
int N, M;

void cityInit()
{
	for (int i = 1; i <= N; i++)
	{
		city[i] = INF;
	}
	city[1] = 0;
}

void makeEdge()
{
	//간선 가중치의 최솟값을 받기 위해서
	//make edge;
	int s, e, dis;
	for (int i = 0; i < M; i++)
	{
		cin >> s >> e >> dis;
		if (tempEdge.count({ s,e }) == 0)
			tempEdge[{s, e}] = dis;
		else
			tempEdge[{s, e}] = min(tempEdge[{s, e}], dis);
	}

	edge.resize(N + 1);
	for (auto& ele : tempEdge)
	{
		s = ele.first.first;
		e = ele.first.second;
		dis = ele.second;

		edge[s].push_back({ e, dis });
	}
}

void checkEdge()
{
	for (int here = 1; here <= N; here++)
	{
		if (city[here] == INF)
			continue;

		for (auto& ele : edge[here])
		{
			int there = ele.first;
			long long dis = ele.second + city[here];

			if (city[there] > dis)
				city[there] = dis;
		}
	}
}

void bellmanFord()
{
	for (int cnt = 1; cnt <= N-1; cnt++)
	{
		checkEdge();
	}
}

bool isMinusCycle()
{
	vector<long long> tempAns;
	tempAns.resize(1);

	for (int i = 1; i <= N; i++)
	{
		tempAns.push_back(city[i]);
	}

	//음수 순환인지 확인
	checkEdge();

	for (int i = 1; i <= N; i++)
	{
		if (tempAns[i] != city[i])
			return true;
	}

	return false;
}

int main()
{
	cin >> N >> M;
	cityInit();
	makeEdge();
	bellmanFord();
	
	if (isMinusCycle())
		cout << -1 << endl;
	else
	{
		for (int i = 2; i <= N; i++)
		{
			if (city[i] == INF)
				cout << -1 << endl;
			else
				cout << city[i] << endl;
		}
	}

	return 0;
}

후기

오버플로우를 의식못하는 기초적인 실수로 약 30분 공중에 날렸다.ㅎ

기본이 중요하다는걸 다시한번 깨닫는 문제였다. 

반응형

'알고리즘 문제풀이' 카테고리의 다른 글

백준 11066번 _ 파일 합치기  (1) 2020.05.04
백준 2293번 _ 동전 1  (0) 2020.05.03
codeforces_ 158B_ Taxi  (0) 2020.05.02
백준 15683번_ 감시  (0) 2020.05.01
백준 14891번 _ 톱니바퀴  (0) 2020.04.30
Comments