Routing C++ 시간초과 문제 도움 부탁드립니다.

  • naka15
    naka15

    ROUTING
    Tutorial에 그래프 Routing 문제 입니다.
    다익스트라 알고리즘을 응용해서 만들었습니다.
    답은 맞게 나오는 듯 한데 시간초과가 뜹니다.
    알고리즘 보다는 코드에 성능측면으로 잘못되거나 비효율적인 부분이 있으면 지적해 주시길 부탁드립니다. 아주 사소한것이라도 좋습니다.
    그리고

    vector<vector<int>> v;
    

    이런식의 데이터 구조는
    int v[][] 와 같은 이차원 배열보다 비효율적인가요?

    //2015/6/11 Algospot.com Routing 시간초과 제한시간 2000ms
    
    
    #include<iostream>
    #include<vector>
    #include<array>
    
    using namespace std;
    
    struct Edge{
        int to;             //엣지와 연결된 노드
        double dist;        //엣지의 길이(noise)
        Edge( int b, double c){
            to=b;
            dist=c;
        }
        Edge(){
        }
    };
    
    class Dijkstra{
    private: 
        int comNum;
        int EdgeNum;
        double *distance;
        bool *visited;
        double *result;
        vector<vector<Edge>> cango; 
    
    public:
        Dijkstra(){
        }
        void Find(int start);
        void in();
    };
    
    void Dijkstra::in(){
        //입력 받기
        int cases;
        cin>>cases;
        int a;
        int b;
        double c;
        result = new double[cases];
        for(int i=0; i<cases; i++){
            cin>>comNum;
            cin>>EdgeNum;
            distance= new double[comNum];
            visited = new bool[comNum];
            cango.clear();
            cango.reserve(comNum);
    
            //cango[i] -> i에서 갈수 있는 Edge의 집합 Vector
    
            for(int j=0; j<comNum; j++){
                cango.push_back(vector<Edge>());
                visited[j]=false;
                distance[j]=0;
            }
            distance[0]=1;
            for(int j=0; j<EdgeNum; j++){
                cin>>a;
                cin>>b;
                cin>>c;
                cango[a].push_back(Edge(b,c));
                cango[b].push_back(Edge(a,c));
            }
    
    
            //답 찾기
            Find(0);
            result[i]=distance[comNum-1];
        }
    
        //결과 출력
        cout<<fixed;
        cout.precision(10);
        for(int i=0; i<cases; i++){
    
            cout<<result[i]<<endl;  
        }
        cin>>cases;
    }
    
    void Dijkstra::Find(int start){
    
        int nowLoc=start;
        int n=0;
        int to=0;
        double dis=0;
        while(n<comNum){
            visited[nowLoc]=true;
            for(int i=0; i<cango[nowLoc].size(); i++){
                to=cango[nowLoc].at(i).to;
                //현재 노드와 연결된 노드들의 distance 계산
                if(!visited[to]){
                    dis=distance[nowLoc] * cango[nowLoc].at(i).dist;
                    if(dis<distance[to]||distance[to]==0){
                        distance[to]=dis;
                    }
                }
    
            }
            double min = 99999999999999;
            int loc = 0;
            double dist;
    
            //distance 값이 가장 작은 위치를 찾아 방문(while 문 반복)
            for(int i=0; i<comNum; i++){
                dist=distance[i];
                if(min>dist&&!visited[i]&&dist!=0){
                    min = dist;
                    loc = i;
                }
            }
            nowLoc = loc;
            n++;
        }
    
    }
    
    int main(){
        Dijkstra d;
        d.in();
    }
    

    8년 전
4개의 댓글이 있습니다.
  • Being
    Being
    1. 입력으로 주어지는 그래프가 무척 큽니다. 자주 하는 실수 모음 페이지의 I/O 처리 속도 항목을 참고하시기 바랍니다.
    2. 다익스트라 알고리즘의 수행 시간도 시간복잡도 오더 수준의 개선이 가능합니다. 지금 알고리즘은 O(V^2 + E)고요, V10000개나 되는데다 케이스가 여러 개이면 느립니다. 다익스트라 알고리즘은 O(V \lg V + E)로 개선할 수 있으니 다른 자료를 참고해 보시기 바랍니다.

    8년 전 link
  • Being
    Being

    O((E+V) \lg V)로 정정합니다 하하..


    8년 전 link
  • naka15
    naka15

    알고리즘이 문제군요ㅠ참고해서 풀어보도록하겠습니다.친절하게 설명 해주셔서 진심으로 감사합니다! 해결되하면 댓글 남기겠습니다!


    8년 전 link
  • naka15
    naka15

    조언 덕분에 해결되었습니다! 이 문제 하나로 몇일을 날린건지ㅠㅠ
    PriorityQueue 쓰고 알고리즘 고치고 입력방식 바꿔서 일단 Java로 해결했습니다. java가 해결됬으니 C++은 더 빠른 결과가 나올것이라 생각합니다. 이제 c++로 구현하러 가야겠습니다. 조언 감사합니다!


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