• 카테고리

    질문 & 답변
  • 세부 분야

    알고리즘 · 자료구조

  • 해결 여부

    미해결

제품이동 질문드립니다.

24.04.22 09:59 작성 조회수 32

0

- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요!
- 먼저 유사한 질문이 있었는지 검색해보세요.
- 서로 예의를 지키며 존중하는 문화를 만들어가요.
- 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.

 

시간 초과라고 뜨는데, 더 빠른 방법이 있나요??

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

class Node{
	int v;
	int c;
	Node(int v, int c){
		this.v=v;
		this.c=c;
	}
}
public class Main {
	public static ArrayList<Node>[] graph;
	public static int n,m,s, e;
    public static void main(String[] argvs) {
        Scanner sc = new Scanner(System.in);
        
        n=sc.nextInt();
        m=sc.nextInt();
        graph = new ArrayList[n+1];
        for(int i=1;i<=n; i++) graph[i] = new ArrayList<>();
        
        for(int i=0; i<m; i++) {
        	int a=sc.nextInt();
        	int b=sc.nextInt();
        	int c=sc.nextInt();
        	graph[a].add(new Node(b,c));
        	graph[b].add(new Node(a,c));
        }
        
        s=sc.nextInt();
        e=sc.nextInt();
        int lt=1;
        int rt = 1000000000;
        int answer=0;
        while(lt<=rt) {
        	int mid = (lt+rt)/2;
        	
        	if(count(mid)==1) { //e정점까지 갈 수있으면
        		answer=mid;
        		lt = mid+1; //최대의 답을 찾아야하니까
        	}
        	else rt = mid-1;
        }
        System.out.print(answer);
    }
    public static int count(int limit) {
    	int[] ck = new int[n+1];
    	Queue<Node> q = new LinkedList<>();
    	q.add(new  Node(s,0));
    	ck[s]=1;
    	
    	while(!q.isEmpty()) {
    		Node now = q.poll();
    		int nowx = now.v;
    		int nowc = now.c;
    		for(Node ob : graph[nowx]) {
    			if(ob.c>=limit && ck[ob.v]==0) {
    				q.add(new Node(ob.v, ob.c));
    				ck[ob.v]=1;
    			}
    		}
    	}
    	return ck[e]; //마지막 점까지 갈수 있다면 1리턴, 아니면 0리턴
    }
}

답변 1

답변을 작성해보세요.

0

인프런 AI 인턴님의 프로필

인프런 AI 인턴

2024.04.24

안녕하세요, 인프런 AI 인턴입니다.

xogh7532님, Java로 구현하신 제품 이동 관련 코드에서 시간 초과 문제를 해결하고자 하시네요. 주어진 코드를 살펴보니 이진 탐색과 너비 우선 탐색(BFS)를 사용하여 특정 조건을 만족하는 최댓값을 찾는 문제 같습니다. 시간 초과 문제를 줄이기 위해 몇 가지 방법을 제안드립니다:

  1. 자료구조 최적화: 현재 ArrayList를 사용하여 간선 정보를 저장하고 있습니다. 데이터 접근 시간을 줄이기 위해 ArrayList 대신 LinkedList를 사용할 수도 있지만, 실제로 시간 단축에 큰 영향을 미치는 것은 아닙니다. 다만, 간선의 개수가 많은 경우 LinkedList가 더 효율적일 수 있습니다.

  2. 이진 탐색 최적화: 이진 탐색 로직 자체를 개선할 여지는 적지만, ltrt 값을 변경할 때의 로직을 최적화하여 불필요한 반복을 줄일 수 있습니다. 하지만 주어진 코드에서는 이미 비교적 효율적으로 처리하고 있어 큰 개선점은 없어 보입니다.

  3. BFS 최적화: count 함수에서 BFS를 수행할 때, ck 배열(방문 여부 체크)을 활용하여 이미 방문한 노드는 다시 방문하지 않도록 처리하고 있습니다. 이 부분은 이미 최적화가 잘 되어 있지만, 큐에 노드를 추가할 때의 조건을 더욱 엄격하게 할 수 있습니다. 예를 들어, 현재 노드에서 갈 수 있는 다른 노드들 중에서 특정 조건(예: 최소 비용보다 큰 경우)을 만족하는 노드로의 이동만 허용하는 등의 조건을 추가할 수 있습니다.

  4. 방문 체크 로직 개선: 큐에 노드를 추가하기 전에 방문 체크를 바로 수행하면 불필요한 큐 삽입을 방지할 수 있습니다. 즉, ck[ob.v]==0 조건을 만족하는 순간 바로 ck[ob.v]를 1로 설정합니다.

  5. 코드 리팩토링: 때로는 코드의 구조를 리팩토링하면서 성능을 개선할 수 있습니다. 예를 들어, 특정 함수의 로직을 간소화하거나, 반복문 내에서 불필요한 연산을 줄이는 등의 작업이 해당됩니다.

하지만, 시간 초과 문제의 가장 큰 원인은 주로 알고리즘의 효율성과 관련있습니다. 따라서, 위의 방안들을 적용해도 문제가 해결되지 않는다면, 다른 접근 방식을 고려해야 할 수도 있습니다. 예를 들어, 전제 조건을 다시 검토하거나 문제를 해결하기 위한 전혀 다른 알고리즘을 고려해 볼 필요가 있습니다.