[백준] 2660번. 회장뽑기

연성·2020년 10월 19일
0

코딩테스트

목록 보기
92/261

[백준] 2660번. 회장뽑기

1. 문제

월드컵 축구의 응원을 위한 모임에서 회장을 선출하려고 한다. 이 모임은 만들어진지 얼마 되지 않았기 때문에 회원 사이에 서로 모르는 사람도 있지만, 몇 사람을 통하면 모두가 서로 알 수 있다. 각 회원은 다른 회원들과 가까운 정도에 따라 점수를 받게 된다.

예를 들어 어느 회원이 다른 모든 회원과 친구이면, 이 회원의 점수는 1점이다. 어느 회원의 점수가 2점이면, 다른 모든 회원이 친구이거나 친구의 친구임을 말한다. 또한 어느 회원의 점수가 3점이면, 다른 모든 회원이 친구이거나, 친구의 친구이거나, 친구의 친구의 친구임을 말한다.

4점, 5점 등은 같은 방법으로 정해진다. 각 회원의 점수를 정할 때 주의할 점은 어떤 두 회원이 친구사이이면서 동시에 친구의 친구사이이면, 이 두사람은 친구사이라고 본다.

회장은 회원들 중에서 점수가 가장 작은 사람이 된다. 회장의 점수와 회장이 될 수 있는 모든 사람을 찾는 프로그램을 작성하시오.

2. 입력

입력의 첫째 줄에는 회원의 수가 있다. 단, 회원의 수는 50명을 넘지 않는다. 둘째 줄 이후로는 한 줄에 두 개의 회원번호가 있는데, 이것은 두 회원이 서로 친구임을 나타낸다. 회원번호는 1부터 회원의 수만큼 붙어 있다. 마지막 줄에는 -1이 두 개 들어있다.

3. 출력

첫째 줄에는 회장 후보의 점수와 후보의 수를 출력하고, 두 번째 줄에는 회장 후보를 오름차순으로 모두 출력한다.

4. 풀이

  • 몇 단계를 거치면 모두가 친구가 되는지 가장 단계가 짧은 사람을 회장으로 세우는 문제다.
  • 그래프를 그리고 생각해보니 결국 최대 깊이를 구하라는 문제였다. 각 노드 별 최대 깊이를 구하고 그 중 깊이가 가장 얕은 사람을 회장으로 세우는 문제였다.

5. 처음 코드와 달라진 점

  • visited 초기화 하지 않아서 문제가 좀 있었다.
  • 모든 노드를 BFS하는 것보다 이미 사용한 정보를 이용할 방법이 없나 고민했지만 그냥 확실하게 하기로 했다. 시간 초과는 발생하지 않았다.
  • 뒤 쪽에 최대 숫자와 개수와 숫자 출력하는 게 구현하기 좀 번거롭고 비효율적인 것 같아서 우선 순위 큐를 이용할까 했지만 우선 그냥 했다.
    추가로 해보려고 했는데 잘 안 되길래 냅뒀다.

6. 코드

#include <iostream>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;

vector<int> graph[51];
int score[51];
int n;

void bfs(int start) {
	bool visited[51] = { 0, };
	int depth[51] = { 0, };
	
	queue<int> q;
	q.push(start);
	
	visited[start] = true;
	depth[start] = 0;

	while (!q.empty()){
		int x = q.front();
		q.pop();
		for (int i = 0; i < graph[x].size(); i++){
			int y = graph[x][i];
			if (!visited[y]) {
				q.push(y);
				visited[y] = true;
				depth[y] = depth[x] + 1;
			}
		}
	}
	
	int maxDepth = depth[1];
	for (int i = 2; i <= n; i++){
		maxDepth = max(maxDepth, depth[i]);
	}
	score[start] = maxDepth;
}

int main() {
	cin.tie(NULL);
	ios_base::sync_with_stdio(false);
    
	cin >> n;
	int from=0, to=0;
	while (true){
		cin >> from >> to;
		if (from == -1 && to == -1) break;
		graph[from].push_back(to);
		graph[to].push_back(from);
	}

	for (int i = 1; i <= n; i++){
		bfs(i);
	}

	int maxScore = score[1];
	for (int i = 2; i <= n; i++){
		maxScore = min(maxScore, score[i]);
	}

	int count = 0;
	for (int i = 1; i <= n; i++){
		if (score[i] == maxScore) count++;
	}
	cout << maxScore << " " << count << "\n";

	for (int i = 1; i <= n; i++) {
		if (score[i] == maxScore) cout<<i<<" ";
	}
}

0개의 댓글