Hoon222y

[BOJ 1944] 복제 로봇 본문

코딩/BOJ & 알고스팟

[BOJ 1944] 복제 로봇

hoon222y 2017. 8. 28. 23:44

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


해당 문제의 경우 시작점과 키가 있는 지점간의 모든 거리를 구해두고 MST를 만들면 된다. 여기서 주의해야 할 점은 

1) S와 K에서만 복제가 가능하기 때문에 57번째 줄 처럼 각각의 거리를 구할 때 K나 S에 도달했을 때에도 Queue에 넣어줘야 한다.

2) 배열의 크기는  M이다 .... 



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
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#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,m,dist[555][555],posnum[555][555],parent[555];
int dx[4= {0,0,-1,1};
int dy[4= {1,-1,0,0};
bool chk(int y, int x){
    return 0<&& y<=&& 0<&& x <=n;
}
char arr[555][555];
bool visit[555][555];
vector<pair<int,int>> v;
vector<pair<int,pair<int,int>>> vt;
 
void bfs(int yy,int xx){
    memset(visit,false,sizeof(visit));
    
    queue<pair<int,int>> q;
    q.push({yy,xx});
    
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            dist[i][j] = INF;
        }
    }
    dist[yy][xx] = 0;
    
    while(!q.empty()){
        int yyy = q.front().first;
        int xxx = q.front().second;
        q.pop();
        
        if(visit[yyy][xxx])continue;
        visit[yyy][xxx] = true;
        
        for(int i=0;i<4;i++){
            int y= yyy+dy[i];
            int x = xxx+dx[i];
            if(chk(y,x)){
                if(arr[y][x] == '0' && dist[y][x] >dist[yyy][xxx]+1){
                    dist[y][x] = dist[yyy][xxx]+1;
                    q.push({y,x});
                }else if((arr[y][x] == 'K' || arr[y][x] == 'S' )&& dist[y][x] == INF){
                    dist[y][x] = dist[yyy][xxx] +1;
                    q.push({y,x});
                }
            }
        }
    }
    
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(arr[i][j] == 'S' || arr[i][j] == 'K'){
                if(dist[i][j] == INF){
                    cout << "-1"<<endl;
                    exit(0);
                }else{
                    vt.push_back({dist[i][j],{posnum[yy][xx],posnum[i][j]}});
                }
            }
        }
    }
}
 
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<=m;i++){
        parent[i] = i;
    }
}
 
int main(){
    memset(visit,false,sizeof(visit));
    memset(posnum,0,sizeof(posnum));
    cin >> n >>m;
    init();
    
    int tmp = 1;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            cin >> arr[i][j];
            if(arr[i][j] == 'K' || arr[i][j] == 'S'){
                posnum[i][j] = tmp;
                tmp++;
                v.push_back({i,j});
            }
        }
    }
    
    for(int i=0;i<v.size();i++){
        int yy = v[i].first;
        int xx = v[i].second;
        bfs(yy,xx);
    }
    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 1939] 중량제한  (0) 2017.08.31
[BOJ 1854] K번째 최단경로 찾기  (0) 2017.08.29
[BOJ 2211] 네트워크 복구  (0) 2017.08.28
[BOJ 2887] 행성터널  (0) 2017.08.28
[BOJ 6497] 전력난  (0) 2017.08.27
Comments