그래프

단지번호붙이기

4gats 2023. 3. 3. 22:57

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

 

2667번: 단지번호붙이기

<그림 1>과 같이 정사각형 모양의 지도가 있다. 1은 집이 있는 곳을, 0은 집이 없는 곳을 나타낸다. 철수는 이 지도를 가지고 연결된 집의 모임인 단지를 정의하고, 단지에 번호를 붙이려 한다. 여

www.acmicpc.net

DFS나 BFS를 이용해 연결요소의 개수를 알아내면 끝

인접 행렬과 인접 리스트를 사용할 필요도 없다!

그냥 행렬의 인덱스의 차이를 이용하자!

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
#define _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <algorithm>
#include <queue>
 
using namespace std;
int a[30][30];
int group[30][30];
int dx[] = { 001-1 };
int dy[] = { 1-10 ,0 };
int n;
int ans[25 * 25];
 
void bfs(int x, int y, int cnt)
{
    //기억해두자 pair와 make_pair
    queue<pair<intint>> q;
    q.push(make_pair(x, y));
    group[x][y] = cnt;
 
    //bfs 시작
    while (!q.empty())
    {
        x = q.front().first;
        y = q.front().second;
        q.pop();
        for (int k = 0; k < 4; k++)
        {
            int nx = x + dx[k];
            int ny = y + dy[k];
            if (0 <= nx && nx < n && 0 <= ny && ny < n)
            {
                if (a[nx][ny] == 1 && group[nx][ny] == 0)
                {
                    //인접한 것은 다 큐에 넣는다
                    q.push(make_pair(nx, ny));
                    group[nx][ny] = cnt;
                }
            }
        }
 
    }
 
}
 
int main()
{
    scanf("%d"&n);
 
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
            scanf("%1d"&a[i][j]); // 한 자리 수만 받으므로!
    }
    int cnt = 0;
 
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
        {
            // bfs 시작 조건
            if (a[i][j] == 1 && group[i][j] == 0)
                bfs(i, j, ++cnt);    // ++cnt!!!
        }
    }
    printf("%d\n", cnt);
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < n; j++)
            ans[group[i][j]] += 1;
    }
 
    //집의 수를 오름차순 정렬
    sort(ans + 1, ans + cnt + 1);
    for (int i = 1; i <= cnt; i++)
        printf("%d\n", ans[i]);
 
    return 0;
}
cs

DFS 버전

 

비슷한 문제

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

 

4963번: 섬의 개수

입력은 여러 개의 테스트 케이스로 이루어져 있다. 각 테스트 케이스의 첫째 줄에는 지도의 너비 w와 높이 h가 주어진다. w와 h는 50보다 작거나 같은 양의 정수이다. 둘째 줄부터 h개 줄에는 지도

www.acmicpc.net

int dx[] = { 0, 0, 1, -1, 1 , 1 , -1, -1 };
int dy[] = { 1, -1, 0 ,0 , 1, -1, 1, -1 };

대각선 까지 가는 것만 추가!