안녕하세요! 테크지니어22입니다.
오늘은 백준 알고리즘 를 풀어보도록 하겠습니다.
https://www.acmicpc.net/problem/2660
[문제 접근]
처음에 문제를 읽고 머릿속에 명확히 문제 상황이 그려지지 않았습니다.
그래서 예제를 토대로 그림을 그려가며 이해를 시도했습니다.
사람을 정점으로, 친구관계를 간선으로 치환하여 생각했고,
조건에서 몇 사람을 통하면 모두가 서로 알 수 있다고 했기 때문에 BFS를 이용해서 거리가 가장 먼 정점을 점수로 두었습니다.
인접리스트를 활용하여 BFS를 둘 경우에는 O(V+E)의 시간복잡도가 걸립니다.
제한시간은 1초이지만, 회원의 수가 50명이하여서, O(V+E) * 50 충분히 제한시간 안에 들어갈 수 있다고 판단하였습니다.
[풀이 전략]
1. 무방향 그래프임을 감안한 인접리스트를 구현
2. score 배열 선언
2.BFS 구현
- 방문여부랑 거리를 포함하는 dis 배열 선언 및 초기화
- 한 정점의 BFS 로직이 끝나면 dis 배열에서 가장 큰 값을 그 정점의 score로 설정.
3. 모든 정점에 대해 2번 반복.
[코드]
#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;
vector<int> adj[51];
int score[51] ;
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
int n ;
cin >> n ;
while (true)
{
int a,b ;
cin >> a >> b ;
if(a == -1 && b == -1) break;
adj[a].push_back(b);
adj[b].push_back(a);
}
fill(score+1,score+n+1,0);
for(int i = 1 ; i <= n ; i++) {
queue<int> q ;
int dis[n+1] ;
fill(dis+1,dis+n+1, -1);
q.push(i);
dis[i] = 0;
while (!q.empty())
{
auto cur = q.front(); q.pop();
for(auto e: adj[cur]) {
if(dis[e] >= 0) continue;
dis[e] = dis[cur] + 1;
q.push(e);
}
}
score[i] = *max_element(dis+1,dis+n+1);
}
int min = *min_element(score+1,score+n+1);
vector<int> result ;
for(int i = 1 ; i <= n ; i++) {
if(score[i] == min) result.push_back(i);
}
cout << min << ' '<< result.size() <<'\n';
for(auto e : result) cout << e << ' ';
}
[배울 점]
- 거리와 방문여부를 나타내는 dis를 처음에 초기화할 때 -1로 할지 혹은 0으로 할지에 대해서 충분히 고민해야 합니다. 만약 처음에 방문한 지점의 dis값을 0으로 설정했는데 dis 초기화값이 0으로 되어 있으면 이 처음 방문 지점은 방문체크가 되지 않습니다.
'알고리즘 > 백준' 카테고리의 다른 글
[백준/C++] 알고리즘 9655번 - 돌 게임 (0) | 2025.02.16 |
---|---|
[백준/C++] 알고리즘 10942번 - 팰린드롬? (0) | 2025.02.16 |
[백준/C++] 알고리즘 1715번 - 카드 정렬하기 (0) | 2024.09.29 |
[백준/C++] 알고리즘 1806번 - 부분 합 (0) | 2024.09.28 |
[백준/C++] 알고리즘 1620번 - 나는야 포켓몬 마스터 이다솜 (3) | 2024.09.28 |