Algorithm

[BOJ] 2146. 다리 만들기

프로그래민 2020. 3. 21. 21:44
반응형

두번의 BFS를 이용하였다.

첫번째 BFS로 각 섬마다 번호를 지정해주었고, isEdge라른 함수를 이용하여 현재 위치가 가장 자리인 것이 확인이 되면 두번째 BFS를 사용하여 다른 섬까지의 거리를 구해주는 방식으로 해결하였다.

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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package chap05;
 
 
public class Main_bj_2146_다리만들기 {
    
    static int N;
    static int[][] island;
    static int[][] map;
    static boolean[][] visit;
    
    static int[] di = {-1,0,1,0};
    static int[] dj = {0,1,0,-1};
    
    static Queue<Pos> queue;
    
    static int islandNumber=0;
    static int result;
    
    static class Pos{
        int i,j;
        int dis;
        public Pos(int i,int j) {
            this.i=i;this.j=j;dis=0;
        }
        public Pos(int i,int j, int d) {
            this.i=i;this.j=j;dis=d;
        }
    }
    
    public static void main(String[] args) throws Exception {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = null;
        
        N=Integer.parseInt(br.readLine());
        visit=new boolean[N][N];
        map=new int[N][N];
        island=new int[N][N];
        queue= new LinkedList<>();
        
        for(int i=0;i<N;i++) {
            st=new StringTokenizer(br.readLine());
            for(int j=0;j<N;j++) {
                map[i][j]=Integer.parseInt(st.nextToken());
            }
        }
        
        bfsFindIsland();        //맵별로 만듬
 
        result=Integer.MAX_VALUE;
        bfsFindDis();
        System.out.println(result);
//        for(int i=0;i<N;i++) {
//            for(int j=0;j<N;j++) {
//                System.out.print(island[i][j] +" ");
//            }
//            System.out.println();
//        }
        
    }
    
    static boolean isEdge(int i,int j) {
        for(int dir=0;dir<4;dir++) {
            int nextI=i+di[dir];
            int nextJ=j+dj[dir];
            
            if(nextI<0 || nextI >=|| nextJ<0 || nextJ>=N)
                continue;
            if(map[nextI][nextJ]==0)
                return true;
        }
        return false;
    }
    
    static void bfsFindIsland() {
        for(int i=0;i<N;i++) {
            for(int j=0;j<N;j++) {
                if(map[i][j]==1 && visit[i][j]==false) {
                    islandNumber++;
                    queue.offer(new Pos(i, j));
                    visit[i][j]=true;
                    island[i][j]=islandNumber;
                    
                    while(!queue.isEmpty()) {
                        Pos cur=queue.poll();
                        
                        for(int dir=0;dir<4;dir++) {
                            int nextI=cur.i+di[dir];
                            int nextJ=cur.j+dj[dir];
                            
                            if(nextI<0 || nextI >=|| nextJ<0 || nextJ>=N)
                                continue;
                            
                            if(map[nextI][nextJ]==1 && visit[nextI][nextJ]==false) {
                                visit[nextI][nextJ]=true;
                                island[nextI][nextJ]=islandNumber;
                                queue.offer(new Pos(nextI, nextJ));
                            }
                        }
                    }
                    
                }
            }
        }
    }
    
    static void bfsFindDis() {
        for(int i=0;i<N;i++) {
            for(int j=0;j<N;j++) {
                if(island[i][j]!=0 && isEdge(i, j)==true) {
                    visit=new boolean[N][N];
                    queue.offer(new Pos(i, j,0));
                    int landNum=island[i][j];
                    
//                    System.out.println(i+","+j+"="+landNum);
                    while(!queue.isEmpty()) {
                        Pos cur= queue.poll();
                        
                        for(int dir=0;dir<4;dir++) {
                            int nextI=cur.i+di[dir];
                            int nextJ=cur.j+dj[dir];
                            
                            if(nextI<0 || nextI >=|| nextJ<0 || nextJ>=N)
                                continue;
                            
//바다인 경우
                            if(island[nextI][nextJ]==0 && visit[nextI][nextJ]==false) {
                                visit[nextI][nextJ]=true;
                                queue.offer(new Pos(nextI, nextJ, cur.dis+1));
                            }
 
                          //육지인 경우
                            if(island[nextI][nextJ]!=0 && island[nextI][nextJ]!=landNum) {
//                                visit[nextI][nextJ]=true;
//                                System.out.print(nextI+","+nextJ+" = "+cur.dis +" >> ");
                                result=Math.min(result, cur.dis);
                            }
                        }
                    }
                }
//                System.out.println();
                
            }
        }
        
        
    }
}
 
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
                                                 
반응형

'Algorithm' 카테고리의 다른 글

[BOJ] 11729. 하노이 탑 이동 순서  (0) 2020.03.22
[BOJ] 1629. 곱셈  (0) 2020.03.22
[BOJ] 12851. 숨바꼭질2  (0) 2020.03.18
[BOJ] 1600. 말이 되고픈 원숭이  (0) 2020.03.18
[BOJ] 13549. 숨바꼭질3  (0) 2020.03.15