LAN 문제 시간초과 질문있습니다~

  • Jinsanger
    Jinsanger

    LAN 문제에 3시간 동안 매달려있는 알고리즘 초짜입니다. ㅜ_ㅜ

    정말 단순하게 스패닝 트리로 구현을 했는데, 왜 시간초과가 나는지 이해를 못하겠네요 ㅠㅠ

    간략하게 설명을 드리자면 맨처음 입력받는 건물에 대해서 건물이 연결되어있는 그룹을 그룹핑하고 이후에 그룹에서 가장 근접한 점들을 찾아서 연결하는 단순한 방식입니다.

    N이 500이라서 복잡도에도 안전하게 들어올줄 알고 구현했는데 시간초과가 뜨네요.
    가지치기할 방법도 안떠오르고... 혹시 이런 단순한 방법으로는 풀리지 않는 문제인가여??

    #include <iostream>
    #include <math.h>
    using namespace std;
    
    static int N = 0;
    static int M = 0;
    
    typedef struct Building{
        double x;
        double y;
        int adjacent[500];
        int adjacent_count;
    }build;
    
    static build buildings[500] = {0, };
    static build spannings[500] = {0, };
    static int spanning_count = 0;
    static int close_building[500] = {0, };
    
    double Sqaure(double value){
        return value * value;
    }
    double Dist(double x_dist, double y_dist){
        return sqrt(Sqaure(x_dist) + Sqaure(y_dist));
    }
    
    void Link(int idx){
        spannings[spanning_count++] = buildings[idx];
        close_building[idx] = 1;
        for(int i=0; i<buildings[idx].adjacent_count; i++){
            if(close_building[buildings[idx].adjacent[i]] == 1)
                continue;
            Link(buildings[idx].adjacent[i]);
        }
    }
    
    double length = 0;
    void LAN(){
        int close_count = 0;
        while(close_count < N && close_building[close_count] == 1)
            close_count++;
        if(close_count == N)
            return ;
    
        double min_dist = 987654321;
        int min_dist_idx = 0;
        for(int i=0; i<spanning_count; i++){
            for(int j=0; j<N; j++){
                if(close_building[j] == 1)
                    continue;
                double dist = Dist(spannings[i].x - buildings[j].x, spannings[i].y - buildings[j].y);
                if(dist < min_dist){
                    min_dist = dist;
                    min_dist_idx = j;
                }
            }
        }
        Link(min_dist_idx);
        length += min_dist;
        LAN();
    }
    
    void Init(){
        for(int i=0; i<N; i++){
            buildings[i].adjacent_count = 0;
            spannings[i].adjacent_count = 0;
            close_building[i] = 0;
        }
        spanning_count = 0;
        length = 0;
    }
    
    int main(void){
        int C=0;
        cin>>C;
        while(C-->0){
            Init();
            cin>>N>>M;
    
            for(int i=0; i<N; i++)
                cin>>buildings[i].x;
            for(int i=0; i<N; i++)
                cin>>buildings[i].y;
    
            for(int i=0; i<M; i++){
                int build_a, build_b;
                cin>>build_a>>build_b;
    
                buildings[build_a].adjacent[buildings[build_a].adjacent_count++] = build_b;
                buildings[build_b].adjacent[buildings[build_b].adjacent_count++] = build_a;
            } 
    
            Link(0);
            LAN();
            cout.precision(10);
            cout<<length<<endl;
        }
        return 0;
    }
    

    9년 전
2개의 댓글이 있습니다.
  • Being
    Being

    O(N^3) 으로 보이는데, 이러면 1초 안에 실행되기엔 좀 빠듯해 보이네요.


    9년 전 link
  • Jinsanger
    Jinsanger

    하아 ㅠㅠ 처음부터 생각을 잘못했군요. 그래프 알고리즘들에 약한데... 다시 공부를 해야겠습니다.


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