문제 출처: https://www.acmicpc.net/problem/1389


풀이

문제 조건에맞게 예제를 그려서 보면 문제에서 원하는 답은 어떤정점에서 각 정점으로 가는 최단거리의 합이 가장 작은 정점임을 알 수 있습니다.

문제를 읽어보면 플로이드와샬 알고리즘으로 풀 수 있음을 짐작 할 수 있습니다.

플로이드 와샬 알고리즘으로 풀 때 한 노드에서 다른 노드로 가는 길이 없을 때를 0이아닌 INF로 채워넣고 푸는 방법과 0으로 초기화시켜놓고 푸는

방법이 있는데, 0으로 초기화 시켜서 풀 경우, "길이 없음"과 최단거리의 의미가 충돌되므로 출발->도착 하는 지점이 없을 경우는

일단 map[i][j]를 출발->거치고->도착하는 값으로 설정시켜줘야합니다. 

저는 INF로 채워놓고 풀었습니다.(취향 차이인 것 같습니다.)


main문에서 배열을 INF로 채워넣지않고(0으로해놓고) 플로이드 3중for문내부 의 주석을 해제하면 0으로 놓고 푸는 풀이가 됩니다.


코드

#include<iostream>
#include<algorithm>
using namespace std;
int INF =10000000;
int n, m, map[101][101], a, b;
int index = 0;
void floyed();
int main()
{
	cin.tie(0);
	cin.sync_with_stdio(false);
	cin >> n >> m;
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= n; j++)
			map[i][j] = INF;
	for (int i = 1; i <= m; i++)
	{
		cin >> a >> b;
		map[a][b] = 1;
		map[b][a] = 1;
	}
	floyed();
	cout << index << '\n';
}
void floyed()
{
	for (int k = 1; k <= n; k++)
	{
		for (int i = 1; i <= n; i++)
		{
			for (int j = 1; j <= n; j++)
			{
				if (i == j)continue;
				/*if (map[i][k] && map[k][j])
				{
					if (map[i][j] == 0)
						map[i][j] = map[i][k] + map[k][j];
					else map[i][j] = min(map[i][j], map[i][k] + map[k][j]);
				}*/
				map[i][j] = min(map[i][j], map[i][k] + map[k][j]);
			}
		}
	}
	int val = 10000000;
	for (int i = 1; i <= n; i++)
	{
		int temp = 0;
		for (int j = 1; j <= n; j++)
		{
			if (i == j)continue;
			temp += map[i][j];
		}
		if (val > temp)
		{
			val = temp;
			index = i;
		}
	}
}


결과


'문제풀이(BOJ) > 플로이드와샬' 카테고리의 다른 글

[백준 1956] 운동  (0) 2020.02.11
[백준 2458] 키 순서  (1) 2020.01.24
[백준 10159] 저울  (0) 2020.01.24
[백준 11403] 경로 찾기  (0) 2020.01.15

+ Recent posts