ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • KOI 2017 고등부 2번 / 문명 - 14868
    Algorithm/BOJ 2020. 9. 12. 21:55
    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
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    #include <iostream>
    #include <queue>
    using namespace std;
     
    int N, K;
    vector<vector<int>> arr;
    queue<pair<intint>> Q[2];
    int xarr[4= {001-1};
    int yarr[4= {1-100};
    bool eFlag = true;
     
    struct DisjointSet {
     
        vector<int> parent, rank;
        int tNum;
     
        DisjointSet() : parent(K), rank(K, 0), tNum(K) {
            for(int i = 0; i<K; ++i)
                parent[i] = i;
        }
     
        int find(int u) {
            if(parent[u] == u) return u;
            return parent[u] = find(parent[u]);
        }
     
        void merge(int u, int v) {
            u = find(u);
            v = find(v);
            if(u == v) return;
            if(rank[u] < rank[v]) swap(u, v);
            parent[v] = u;
            if(rank[u] == rank[v]) ++rank[u];
            --tNum;
            if(1 == tNum) eFlag = false;
        }
    };
     
    bool check(int u, int v) {
        if(u < 1 || u > N || v < 1 || v > N) return false;
        return true;
    }
     
    void init(DisjointSet& set) {
        arr = vector<vector<int>>(N+1vector<int>(N+1-1));
        Q[0= Q[1= queue<pair<intint>>();
        int u, v;
        for(int i = 0; i<K; ++i) {
            cin >> u >> v;
            arr[u][v] = i;
            for(int j = 0; j<4++j) {
                int au = u + xarr[j];
                int av = v + yarr[j];
                if(check(au, av))
                    if(arr[au][av] != -1) set.merge(arr[u][v], arr[au][av]);
            }
            Q[0].push(make_pair(u, v));
        }
    }
     
    int main() {
        ios_base::sync_with_stdio(0), cin.tie(0);
     
        cin >> N >> K;
        DisjointSet set;
        init(set);
        int cnt = 0;
     
        while(eFlag) {
            while(eFlag && !Q[cnt%2].empty()) {
                int x = Q[cnt%2].front().first;
                int y = Q[cnt%2].front().second;
                Q[cnt%2].pop();
                for(int i = 0; i<4++i) {
                    int nx = x+xarr[i], ny = y+yarr[i];
                    if(check(nx, ny)) {
                        if(arr[nx][ny] == -1) {
                            Q[(cnt+1)%2].push(make_pair(nx, ny));
                            arr[nx][ny] = arr[x][y];
     
                            for(int j = 0; j<4++j) {
                                int nnx = nx+xarr[j], nny = ny+yarr[j];
                                if(check(nnx, nny)) {
                                    if(arr[nnx][nny] != -1) set.merge(arr[x][y], arr[nnx][nny]);
                                }
                            }
                        }
                    }
                }
            }
            ++cnt;
        }
        cout << cnt;
    }
    cs

     

     

     

     

     

    www.acmicpc.net/problem/14868

     

    14868번: 문명

    표준 입력으로 다음 정보가 주어진다. 첫 번째 줄에는 세계의 크기를 나타내는 정수 N(2 ≤ N ≤ 2,000)과 문명 발상지의 수 K(1 ≤ K ≤ 100,000)가 주어진다. 다음 K줄에는 한 줄에 하나씩 문명 발상지�

    www.acmicpc.net

     

     

     

     

     

    문명

    BFS와 유니온-파인드로 해결할 수 있습니다. 주의할 점은 문명끼리 이어질때는 추가된 영토에 인접한 다른 문명이 있으면 이어지는데 맨 처음 주어지는 데이터에선 인접해 있더라도 같은 문명으로 취급되지 않는 데이터가 들어오기 때문에 인접한 문명끼리 하나의 문명으로 합쳐주는 전처리과정이 필요합니다.

     

     

     

     

     

    댓글

Designed by Tistory.