백준/그래프

백준 1389 c++ "케빈 베이컨의 6단계 법칙" -PlusUltraCode-

PlusUltraCode 2024. 9. 6. 19:32

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

 

 

[필자 사고]

문제를 읽고 이해를 해보면 다음과 같다.

1. 얼만큼의 친구들이 건너건너 있냐 => 모든 경로의 최단경로를 구한뒤 합을 구하면 케빈 베이컨법칙의 합이 만들어진다.

2. 모든 경로를 구하기 위해 플로이드 와샬 알고리즘이 재격이다.

 

이 문제에서 조심해야 될 점은 가중치 값을 1로 설정하고 se만 설장할게 아니라 es도 양방향 선택해서 주입해야된다.

 

아래는 소스코드 해설이다.

 

 

Input() 함수

  • Input() 함수는 먼저 사용자로부터 노드의 수 N과 간선의 수 M을 입력받는다.
  • 그런 다음, 2차원 벡터 arr를 노드의 개수에 맞춰 초기화한다. 각 노드 간의 초기값은 매우 큰 수인 99999로 설정되며, 자기 자신으로의 경로(arr[i][i])는 0으로 설정된다.
  • 이후, 사용자로부터 입력받은 간선 정보(s, e)를 통해 두 노드가 연결되어 있음을 2차원 배열에 반영하고, 양방향으로 연결되었음을 고려해 arr[s][e]와 arr[e][s] 모두 1로 설정한다.
  •  
  • Floid_Warshall() 함수 Floid_Warshall() 함수는 플로이드-와샬 알고리즘을 사용하여 모든 노드 간의 최단 경로를 계산한다.
  • 세 개의 중첩된 반복문을 사용해 중간 노드 k를 경유하는 경로가 더 짧은지 확인하고, 더 짧으면 그 값을 갱신한다. 이렇게 하면 모든 노드 쌍에 대한 최단 경로가 구해진다.

 

  • GameStart() 함수 GameStart() 함수는 먼저 Floid_Warshall()을 호출하여 모든 노드 간의 최단 경로를 구한 후, 각 노드에서 다른 모든 노드까지의 최단 경로의 합을 계산한다.
  • 이를 위해 resultList라는 벡터를 사용하여 각 노드별 경로 합계를 저장한다.
  • 그 후, min_element 함수를 사용하여 최소 합계를 찾고, 그 합계를 가진 노드를 출력한다. 이는 다른 노드들과의 총 거리 합이 가장 작은 노드, 즉 중심 노드를 구하는 과정이다.

 

 

[소스 코드]

#include <iostream>
#include <vector>
#include<algorithm>

using namespace std;

int N, M;
vector<vector<int>> arr;

void Input() {
	cin >> N >> M;
	arr.resize(N + 1);
	for (int i = 0; i <= N; i++) {
		arr[i].resize(N + 1, 99999);
		arr[i][i] = 0;
	}

	for (int i = 0; i < M; i++) {
		int s, e;
		cin >> s >> e;
		arr[s][e] = 1;
		arr[e][s] = 1;
	}
}

void Floid_Warshall() {

	for (int k = 1; k <= N; k++) {
		for (int s = 1; s <= N; s++) {
			for (int e = 1; e <= N; e++) {
				if (arr[s][e] > arr[s][k] + arr[k][e]) {
					arr[s][e] = arr[s][k] + arr[k][e];
				}
			}
		}
	}
}

void GameStart() {
	Floid_Warshall();

	vector<int> resultList;
	resultList.resize(N + 1);

	for (int i = 1; i <= N; i++) {
		int sum = 0;
		for (int k = 1; k <= N; k++) {
			if (arr[i][k] == 99999)continue;
			sum += arr[i][k];
		}
		resultList[i] = sum;
	}

	int minNum = *min_element(resultList.begin()+1, resultList.end());
	
	for (int i = 1; i <= N; i++) {
		if (minNum == resultList[i]) {
			cout << i;
			return;
		}
	}
}

int main(void) {
	Input();
	GameStart();
}