그래프
단지번호붙이기
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[] = { 0, 0, 1, -1 };
int dy[] = { 1, -1, 0 ,0 };
int n;
int ans[25 * 25];
void bfs(int x, int y, int cnt)
{
//기억해두자 pair와 make_pair
queue<pair<int, int>> 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 };
대각선 까지 가는 것만 추가!