ROUTING 문제에서 RTE (nonzero return code) 에러 코드가 납니다..

  • tkagksmsen
    tkagksmsen

    ROUTING 문제를 다익스트라 알고리즘을 통해서 풀었는데

    샘플로 검증을 한 이후 이를 제출할 때 위의 에러가 뜹니다.

    어떤 케이스에서 나는지 잘 모르겠습니다..

    혹시 봐주실 수 있으신가요;;


    import java.util.ArrayList;
    import java.util.List;
    import java.util.Scanner;

    public class Routing {

    public int itemCnt;
    public double[] results;
    
    public static void main(String[] args) {
        new Routing();
    }
    
    public Routing() {
        getInput();
    }
    
    public void getInput() {
    
        Scanner scn = new Scanner(System.in);
    
        itemCnt = scn.nextInt();
        results = new double[itemCnt];
        for(int i = 0; i < itemCnt; i++) {
            int n = scn.nextInt();
            int m = scn.nextInt();
            double[][] noise = new double[n][n];
    
            for(int j = 0; j < n; j++) {
                for(int k = 0; k < n; k++)
                    noise[j][k] = Double.MAX_VALUE;
            }
    
            for(int j = 0; j < m; j++) {
                int from = scn.nextInt();
                int to = scn.nextInt();
                double cost = scn.nextDouble();
    
                noise[from][to] = cost;
                noise[to][from] = cost;
            }
    
            results[i] = process(noise, n, m);
        }
    
        print();
        scn.close();
    }
    
    public double process(double[][] noise, int n, int m) {
        double[] dTable = new double[n];
        List<Integer> q = new ArrayList<Integer>();
        for(int i = 0; i < n; i++) {
            q.add(i);
            dTable[i] = Double.MAX_VALUE;
        }
        int currentNode = q.remove(0);
        dTable[0] = 1;
    
    
        while(q.size() != 0) {
            //간선이 있을때
            //테이블에 있는 값보다 적은 Cost로 목적지에 도달할 수 있다면 교체
    
    
            for(int i = 0; i < noise[currentNode].length; i++) {
                if(noise[currentNode][i] != Double.MAX_VALUE) {
                    double valueForChange = dTable[currentNode] * noise[currentNode][i];
                    if(dTable[i] > valueForChange)
                        dTable[i] = valueForChange;
                }
            }
    
            //다음 진행을 위한 최소값 찾기
            int next = -1;
            double min = Double.MAX_VALUE;
            for(int i = 0; i < dTable.length; i++){
                if(min > dTable[i] && q.contains(i)) {
                    min = dTable[i];
                    next = i;
                }
            }
    
            //다음 진행값 입력
            for(int i = 0; i < q.size(); i++) {
                if(next == q.get(i)) {
                    currentNode = q.remove(i);
                    break;
                }
            }
        }
    
        return dTable[n - 1];
    }
    
    public void print() {
        for(int i = 0; i < itemCnt; i++) {
            String tmp = String.format("%.11f", results[i]);
            System.out.println(tmp.substring(0, tmp.length() - 1));
        }
    }

    }


    10년 전
2개의 댓글이 있습니다.
  • gwpark
    gwpark

    저랑 동일하게 구현하셨고, 저랑 동일한 실수를 하셨네요.

    double[][] noise = new double[n][n]

    위처럼 선언하시게 되면 N = 10000일 경우 메모리를 총 800,000,000 Byte 사용하게 됩니다. 참고로 문제의 메모리 제한은 65,536,000 Byte죠... 메모리 넘어가서 생기는 문제입니다.

    저렇게 할 경우 배열의 최대 장점인 random access를 '포기'해야 한다는 결론에 이르죠. 뭐 소수(floating point number)를 4bit에 저장할 수 있는 기술이 있다면 모를까 ㅎㅎ (농담임)

    그래서 저 같은 경우는 noise를 HashMap에 저장시켰어요. 그랬더니 '시간초과'가 나오더라고요. 그래서 HashMap이 느린가보다... 싶어서 직접 그에 상응하는 객체를 만들었어요. HashMap과 비슷하게 동작할 수 있도록.

    static class DistBetween {
    ArrayList[] destArr; // destination array
    ArrayList[] distArr; // distance array

    DistBetween(int totalNodeNum) {
        destArr = new ArrayList[totalNodeNum];
        distArr = new ArrayList[totalNodeNum];
        for(int i = 0; i < totalNodeNum; i++) {
            destArr[i] = new ArrayList<>(totalNodeNum / 3);
            distArr[i] = new ArrayList<>(totalNodeNum / 3);
        }
    }
    
    void put(int nodeFrom, int nodeTo, double distVal) {
        int _from = (nodeFrom < nodeTo) ? nodeFrom : nodeTo;
        int _to   = (nodeFrom < nodeTo) ? nodeTo : nodeFrom;
        destArr[_from].add(_to);
        distArr[_from].add(distVal);
    }
    
    double get(int nodeFrom, int nodeTo) {
        int _from = (nodeFrom < nodeTo) ? nodeFrom : nodeTo;
        int _to   = (nodeFrom < nodeTo) ? nodeTo : nodeFrom;
        int idx = destArr[_from].indexOf(new Integer(_to));
        if(idx == -1)
            return INFINITY;
        return distArr[_from].get(idx);
    }

    }

    위와 같은 방식으로 만들면... 메모리 오버 안되게 돌릴 수는 있죠. 근데 역시 시간초과 나옵니다 ㅎㅎㅠㅠㅠㅠㅠ 글쓴 분께서도 한번 메모리 오버 안되게 고쳐보세요.


    10년 전 link
  • jaehyeuck
    jaehyeuck

    아.. 어렵네요 ㅠㅠ


    9년 전 link
  • 정회원 권한이 있어야 커멘트를 다실 수 있습니다. 정회원이 되시려면 온라인 저지에서 5문제 이상을 푸시고, 가입 후 7일 이상이 지나셔야 합니다. 현재 문제를 푸셨습니다.