코딩테스트

[백준 17182] 우주 탐사선 c++ (플로이드 + 완전탐색 )

코앤미 2023. 8. 29. 14:43

문제 링크

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

 

17182번: 우주 탐사선

우주 탐사선 ana호는 어떤 행성계를 탐사하기 위해 발사된다. 모든 행성을 탐사하는데 걸리는 최소 시간을 계산하려 한다. 입력으로는 ana호가 탐색할 행성의 개수와 ana호가 발사되는 행성의 위

www.acmicpc.net

 

문제 풀이

문제를 유심히 읽어야한다.   K 번행성에서 시작해서 모든 행성을 거치는 최단경로를 찾는 것이다.

하지만 주의할 점이 a->b에 경로가 잇더라도, a->c->b와 같이 다른 곳을 거치는 것이 더 빠른 경로일 수 도 있다는 것이다.

따라서 각 정점들간의 최단 거리를 플로이드 와샬을 통해 구하는 것으로 '실제 각 정점간 최단거리' 를 찾은 뒤, 정점 방문 순서의 모든 경우의 수를 완전탐색(permutation) 으로 탐색하며 각 경우의 수에서의 '전체 방문 시간' 을 찾는다.

이중 '최단 거리' 인 것을 출력하면 끝이다.

 

정답 코드

#include<iostream>
#include<queue>
using namespace std;
#include<math.h>
//2:00 ~ 2:40
struct Edge {
	int a;
	int b;
	int cost;
	bool operator <(Edge other)const  {
		return cost > other.cost;
	}
};

int parent[11];

int find(int a) {
	if (parent[a] == a)return a;
	parent[a] = find(parent[a]);
	return parent[a];
}

void join(int a, int b) {
	parent[a] = b;
}
int arr[11][11];
int dist[11][11];//dp
int visit[11];
int answer = 987654321;
int N, K;
void per(int now,int depth,int sum) {
	if (depth == N-1) {
		if (answer > sum)answer = sum;
		return;
	}
	for (int i = 0; i < N; i++) {
		if (visit[i])continue;
		visit[i] = 1;
		per(i,depth+1,sum+dist[now][i]);
		visit[i] = 0;
	}
}

int main() {
	
	vector<pair<int, int>> e[11];
	priority_queue<Edge> pq;
	cin >> N >> K;
	int a, b, c;
	for (int i = 0; i <= N; i++) {
		parent[i] = i;
	}
	for (int i = 0; i < N; i++){
		for (int j = 0; j < N; j++) {
			cin >> dist[i][j];
		}
	}

	for (int k = 0; k < N; k++) {
		for (int i = 0; i < N; i++) {
			for (int j = 0; j < N; j++) {
				dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
			}
		}
	}
	//완탐으로 행성 방문 순서정하자( 첫방문 )
	// 위와 같이 플로이드 적용하는 것으로 어딘가 거쳐서 가는 경우의 수 고려한 최단거리값이 적용된다.	visit[K] = 1;
	visit[K] = 1;
	per(K, 0, 0);
	
	cout << answer;
}