본문 바로가기
개발자/Algorithm

[백준] 1956번 운동

by 평범한A 2023. 5. 21.
반응형

문제정리

1. 사이클을 이루는 도로의 길이의 합이 최소가 되도록 한다.

2. 각 마을(1~V) 어디에서 시작해도 상관없다.(시작한 마을로 다시 돌아와야한다.)

풀이방법

플로이드 워셜 알고리즘

소스

package boj;

import java.io.*;
import java.util.*;

public class BOJ_1956_운동 {
	
	static BufferedReader br;
	static StringTokenizer st;
	static int V; //마을 갯수
	static int E; //도로 갯수
	static int[][] arr;
	static int minDistance = Integer.MAX_VALUE;
	static boolean[] visitCheck;
	
	public static void main(String[] args) throws IOException {
		br = new BufferedReader(new InputStreamReader(System.in));
		st = new StringTokenizer(br.readLine());
		V = Integer.parseInt(st.nextToken());
		E = Integer.parseInt(st.nextToken());
		
		arr = new int[V+1][V+1];
		
		for(int i=0; i<E; i++) {
			st = new StringTokenizer(br.readLine());
			int fromPoint = Integer.parseInt(st.nextToken());
			int ToPoint = Integer.parseInt(st.nextToken());
			int distance = Integer.parseInt(st.nextToken());
			arr[fromPoint][ToPoint] = distance;
		}
		
		for(int i=1; i<V; i++) {
			visitCheck = new boolean[V+1];
			dfs(i,0,i);
		}
		
		if(minDistance == Integer.MAX_VALUE) {
			minDistance = -1;
		}
		System.out.println(minDistance);
	}
	
	public static void dfs(int from, int curr, int destination){
		
		// 계산도중 거리가 최소거리보다 길어도 멈춤
		if(minDistance < curr) {
			return;
		}
		
		// 다시 시작점으로 돌아왔을때 지금까지 확인한 거리와 비교
		if(curr !=0 && from == destination) {
			if(minDistance > curr) {
				minDistance = curr;
				return;
			}
		}
		
		for(int i=1; i<=V; i++) {
			if(arr[from][i] != 0 && !visitCheck[i]) {
				visitCheck[i] = true; 
				dfs(i, curr+arr[from][i], destination);
				visitCheck[i] = false;
			}
		}
	}
}

위처럼 풀었을때는 1964ms초가 걸린다.

그런데 플로이드 워셜 알고리즘을 사용했을때는,,

package boj;

import java.io.*;
import java.util.*;

public class BOJ_1956_운동_재 {
	
	static BufferedReader br;
	static StringTokenizer st;
	static int V; //마을 갯수
	static int E; //도로 갯수
	static int[][] arr;
	static int minDistance = Integer.MAX_VALUE;
	
	public static void main(String[] args) throws IOException {
		br = new BufferedReader(new InputStreamReader(System.in));
		st = new StringTokenizer(br.readLine());
		V = Integer.parseInt(st.nextToken());
		E = Integer.parseInt(st.nextToken());
		int INF = Integer.MAX_VALUE;
		
		arr = new int[V+1][V+1];
		
		for(int i=0; i<E; i++) {
			st = new StringTokenizer(br.readLine());
			int fromPoint = Integer.parseInt(st.nextToken());
			int ToPoint = Integer.parseInt(st.nextToken());
			int distance = Integer.parseInt(st.nextToken());
			arr[fromPoint][ToPoint] = distance;
		}
		
		//길이가 주어지지 않은 값은 10000000(큰값)으로 초기화
		for(int i=1; i<=V; i++) {
			for(int j=1; j<=V; j++) {
				if(arr[i][j]==0) {
					arr[i][j] = INF;
				}
			}
		}
		
		for(int a=1; a<=V; a++) { // a는 시작점
			for(int b=1; b<=V; b++) { //b는 도착점
				
				//시작점과 도착점이 같다면 넘어간다.
				if(a == b) continue; 
				
				//k는 거쳐가는 지점
				for(int k=1; k<=V; k++) { 
					if(a != k && b != k && INF != arr[a][k] && INF != arr[k][b]) {
						arr[a][b] = Math.min(arr[a][b], arr[a][k]+arr[k][b]);
					}
				}
			}
		}
		
		for(int a=1; a<=V; a++) { // a는 시작점
			for(int b=1; b<=V; b++) { //b는 도착점
				if(a != b && arr[a][b]!=INF && arr[b][a]!=INF) { 
					minDistance = Math.min(arr[a][b]+arr[b][a],minDistance);
				}
			}
		}
		
		if(minDistance == Integer.MAX_VALUE) {
			minDistance = -1;
		}
		
		System.out.println(minDistance);
	}
}

640ms 가 걸린다.

반응형

'개발자 > Algorithm' 카테고리의 다른 글

[백준] 1629번 곱셈 - JAVA 풀이  (0) 2023.06.18

댓글