※ 글쓴이는 취미로 코딩을 익혀보는 사람이라 정확하지 않은 내용을 담고 있을 수 있다 ※
이번에 볼 문제는 백준 23324번 문제인 어려운 모든 정점 쌍 최단 거리이다.
문제는 아래 링크를 확인하자.
https://www.acmicpc.net/problem/23324
23324번: 어려운 모든 정점 쌍 최단 거리
첫 번째 줄에 정점의 개수 $N$($2 \le N \le 100\,000$), 간선의 개수 $M$($1 \le M \le 200\,000$), 정수 $K$($1 \le K \le M$)가 주어진다. 다음 $M$개의 줄에 걸쳐 $u_i$와 $v_i$가 주어진다. 이것은 $i$번째 간선은 $u_i$
www.acmicpc.net
주어진 그래프는 연결그래프라는 점을 잘 이용해보자.
주어진 그래프에서 가중치가 1인 간선을 지웠을 때, 해당 그래프는 (1)연결그래프이거나 (2)연결요소가 둘인 그래프로 바뀌게 될 것이다. 각 경우의 답이 어떻게 나오는지 살펴보자.
(1) 연결그래프일 경우, 어떤 두 노드를 골라도 가중치가 0인 간선만을 이용하여 서로를 연결하는 경로가 존재하므로 답은 0이 된다.
(2) 연결요소가 둘인 그래프로 바뀌게 되면 같은 연결요소 안의 두 노드를 고르면 둘 사이 최단경로는 0, 각 연결요소에서 하나씩의 노드를 고르면 둘 사이 최단경로는 1이 된다. 따라서 각 연결요소의 크기를 구해 곱한 값이 답이 된다.
위의 내용을 구현해 문제를 해결하자. 그래프의 연결요소의 크기는 dfs나 bfs와 같은 그래프 탐색 알고리즘 또는 disjoint set과 같은 자료구조를 이용해 간단히 구할 수 있다.
아래는 제출한 소스코드이다.
#include <iostream>
#include <vector>
using namespace std;
typedef long long ll;
ll N, M, K;
vector<int> G[100001];
bool visited[100001];
ll dfs(int cur) {
ll ret = 1;
for (auto& node : G[cur]) {
if (visited[node]) continue;
visited[node] = 1;
ret += dfs(node);
}
return ret;
}
int X, Y;
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cin >> N >> M >> K;
for (int k = 1; k <= M; k++) {
int x, y; cin >> x >> y;
if (k == K) X = x, Y = y;
else {
G[x].emplace_back(y);
G[y].emplace_back(x);
}
}
visited[X] = 1;
ll cnt1 = dfs(X);
if (visited[Y]) {
cout << 0;
return 0;
}
visited[Y] = 1;
ll cnt2 = dfs(Y);
cout << cnt1 * cnt2;
}
'BOJ' 카테고리의 다른 글
[BOJ 27214 // C++] Сетка (0) | 2023.01.20 |
---|---|
[BOJ 24838 // C++] 배열 구간합 놀이 (1) | 2023.01.19 |
[BOJ 27220 // C++] Ромб (0) | 2023.01.18 |
[BOJ 23323 // C++] 황소 다마고치 (0) | 2023.01.18 |
[BOJ 27246 // C++] Различные квадраты (0) | 2023.01.18 |