Hoon222y

[BOJ 2887] 행성터널 본문

코딩/BOJ & 알고스팟

[BOJ 2887] 행성터널

hoon222y 2017. 8. 28. 15:40

https://www.acmicpc.net/problem/2887


모든 행성이 연결되는 MST를 만드는 문제이다. 하지만 보통 구하느 MST와는 다르게 N의 제한이 10만이기 때문에 모든 간선의 길이를 다 넣어주게 되면 O(N^2)으로 시간초과&메모리 초과 콤비를 맞게 될 것이다. 

따라서 간선을 넣어줄 때 필요한 부분만 넣어주는 처리가 필요하다. 


핵심은 거리가 Min(x절대값 차이, y절대값 차이, z절대값 차이) 이므로 각각 x,y,z를 기준으로 sort해준 다음 인전한 경우에만 거리를 넣어주는 3N의 시간복잡도를 넣어주게 되면 해결할 수 있다. 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
#include <stack>
#include <deque>
#include <queue>
#include <cmath>
#include <stdio.h>
 
#define INF 1e9
typedef long long ll;
using namespace std;
 
int n,parent[111111];
 
vector<pair<int,int>> v1;
vector<pair<int,int>> v2;
vector<pair<int,int>> v3;
 
vector<pair<int,pair<int,int>>> vt;
 
int find(int x){
    if(x == parent[x]){
        return x;
    }else{
        return parent[x] = find(parent[x]);
    }
}
void merge(int x, int y){
    x = find(x);
    y = find(y);
    parent[x] = y;
}
void init(){
    for(int i=0;i<=n;i++){
        parent[i] = i;
    }
}
 
int main(){
    cin >>n;
    for(int i=1;i<=n;i++){
        int a,b,c;
        cin>> a >>>>c;
        v1.push_back({a,i});
        v2.push_back({b,i});
        v3.push_back({c,i});
    }
    
    sort(v1.begin(),v1.end());
    sort(v2.begin(),v2.end());
    sort(v3.begin(),v3.end());
    
    for(int i=0;i<v1.size()-1;i++){
        vt.push_back({(abs)(v1[i].first-v1[i+1].first),{v1[i].second,v1[i+1].second}});
        vt.push_back({(abs)(v2[i].first-v2[i+1].first),{v2[i].second,v2[i+1].second}});
        vt.push_back({(abs)(v3[i].first-v3[i+1].first),{v3[i].second,v3[i+1].second}});
    }
    init();
    sort(vt.begin(),vt.end());
    
    int ans = 0;
    for(int i=0;i<vt.size();i++){
        auto p = vt[i];
        int x = find(p.second.first);
        int y = find(p.second.second);
        
        if(x!= y){
            merge(x,y);
            ans += p.first;
        }
    }
    cout <<ans <<endl;
 
    return 0;
}
 
cs


'코딩 > BOJ & 알고스팟' 카테고리의 다른 글

[BOJ 1944] 복제 로봇  (0) 2017.08.28
[BOJ 2211] 네트워크 복구  (0) 2017.08.28
[BOJ 6497] 전력난  (0) 2017.08.27
[BOJ 1946] 신입 사원  (0) 2017.08.27
[BOJ 2458] 키 순서  (0) 2017.08.27
Comments