Skip to content

Commit 7594643

Browse files
committed
[Silver II] Title: 알고리즘 수업 - 너비 우선 탐색 4, Time: 188 ms, Memory: 13784 KB -BaekjoonHub
1 parent 790f8ed commit 7594643

File tree

2 files changed

+101
-0
lines changed

2 files changed

+101
-0
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
# [Silver II] 알고리즘 수업 - 너비 우선 탐색 4 - 24447
2+
3+
[문제 링크](https://www.acmicpc.net/problem/24447)
4+
5+
### 성능 요약
6+
7+
메모리: 13784 KB, 시간: 188 ms
8+
9+
### 분류
10+
11+
너비 우선 탐색, 그래프 이론, 그래프 탐색, 정렬
12+
13+
### 제출 일자
14+
15+
2025년 3월 4일 14:15:09
16+
17+
### 문제 설명
18+
19+
<p>오늘도 서준이는 너비 우선 탐색(BFS) 수업 조교를 하고 있다. 아빠가 수업한 내용을 학생들이 잘 이해했는지 문제를 통해서 확인해보자.</p>
20+
21+
<p><em>N</em>개의 정점과 <em>M</em>개의 간선으로 구성된 무방향 그래프(undirected graph)가 주어진다. 정점 번호는 1번부터 <em>N</em>번이고 모든 간선의 가중치는 1이다. 정점 <em>R</em>에서 시작하여 너비 우선 탐색으로 만들어 지는 트리를 너비 우선 탐색 트리라고 하자. 너비 우선 탐색 트리에 있는 <em>i</em>번 노드의 깊이(depth)를 <em>d<sub>i</sub></em>라고 하자. 시작 정점 <em>R</em>의 깊이는 0이고 방문 되지 않는 노드의 깊이는 -1이다. 정점 <em>R</em>에서 시작하여 너비 우선 탐색으로 노드를 방문할 경우 <em>i</em>번 노드의 방문 순서를 <em>t<sub>i</sub></em>라고 하자. 시작 정점의 방문 순서는 1이고 시작 정점에서 방문할 수 없는 노드는 0이다. 모든 노드에 대한 <em>d<sub>i</sub></em> × <em>t<sub>i</sub></em> 값의 합을 구해보자.</p>
22+
23+
<p>너비 우선 탐색 의사 코드는 다음과 같다. 인접 정점은 <strong>오름차순</strong>으로 방문한다.</p>
24+
25+
<pre>bfs(V, E, R) { # V : 정점 집합, E : 간선 집합, R : 시작 정점
26+
for each v ∈ V - {R}
27+
visited[v] <- NO;
28+
visited[R] <- YES; # 시작 정점 R을 방문 했다고 표시한다.
29+
enqueue(Q, R); # 큐 맨 뒤에 시작 정점 R을 추가한다.
30+
while (Q ≠ ∅) {
31+
u <- dequeue(Q); # 큐 맨 앞쪽의 요소를 삭제한다.
32+
for each v ∈ E(u) # E(u) : 정점 u의 인접 정점 집합.(정점 번호를 <strong>오름차순</strong>으로 방문한다)
33+
if (visited[v] = NO) then {
34+
visited[v] <- YES; # 정점 v를 방문 했다고 표시한다.
35+
enqueue(Q, v); # 큐 맨 뒤에 정점 v를 추가한다.
36+
}
37+
}
38+
}</pre>
39+
40+
### 입력
41+
42+
<p>첫째 줄에 정점의 수 <em>N</em> (5 ≤ <em>N</em> ≤ 100,000), 간선의 수 <em>M</em> (1 ≤ <em>M</em> ≤ 200,000), 시작 정점 <em>R</em> (1 ≤ <em>R</em> ≤ <em>N</em>)이 주어진다.</p>
43+
44+
<p>다음 <em>M</em>개 줄에 간선 정보 <code><em>u</em> <em>v</em></code>가 주어지며 정점 <em>u</em>와 정점 <em>v</em>의 가중치 1인 양방향 간선을 나타낸다. (1 ≤ <em>u</em> < <em>v</em> ≤ <em>N</em>, <em>u</em> ≠ <em>v</em>) 모든 간선의 (<em>u</em>, <em>v</em>) 쌍의 값은 서로 다르다.</p>
45+
46+
### 출력
47+
48+
<p>첫째 줄에 모든 노드에 대한 <em>d<sub>i</sub></em> × <em>t<sub>i</sub></em> 값의 합을 출력한다.</p>
49+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
#include <iostream>
2+
#include <vector>
3+
#include <queue>
4+
#include <algorithm>
5+
#include <cstring>
6+
7+
#define MAX 200001
8+
#define LL long long int
9+
using namespace std;
10+
11+
LL visited[MAX];
12+
LL answer[MAX];
13+
vector<int> graph[MAX];
14+
15+
int main() {
16+
int N, M, R;
17+
cin >> N >> M >> R;
18+
for (int i = 0; i < M; i++) {
19+
int u, v;
20+
cin >> u >> v;
21+
graph[u].push_back(v);
22+
graph[v].push_back(u);
23+
}
24+
25+
int index = 1;
26+
memset(visited, -1, sizeof(visited));
27+
28+
queue<int> q;
29+
q.push(R);
30+
visited[R] = 0;
31+
answer[R] = index;
32+
while (!q.empty()) {
33+
int n_n = q.front();
34+
q.pop();
35+
36+
sort(graph[n_n].begin(), graph[n_n].end());
37+
for (int nn_n : graph[n_n]) {
38+
if (visited[nn_n] != -1) continue;
39+
q.push(nn_n);
40+
visited[nn_n] = visited[n_n] + 1;
41+
answer[nn_n] = ++index;
42+
}
43+
}
44+
45+
LL ans = 0;
46+
for (int i = 1; i <= N; i++) {
47+
ans += answer[i] * visited[i];
48+
}
49+
cout << ans;
50+
51+
return 0;
52+
}

0 commit comments

Comments
 (0)