Problem Solving/BOJ

[백준 / BOJ] C++ 2660 회장뽑기

nageune 2023. 3. 3. 02:27
728x90
반응형

2660번: 회장뽑기

 

문제

https://www.acmicpc.net/problem/2660

 

2660번: 회장뽑기

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

www.acmicpc.net

 

 

풀이

어느 회원이 다른 모든 회원과 연결연결되어 있으면서 점수가 가장 작으면 회장 후보가 된다. 회장 후보가 되기 위한 점수와 회장 후보의 수, 그리고 누가 회장 후보인지 구하는 문제다.

 

각 회원 간 관계를 구해야 하므로 플로이드-워셜 알고리즘을 사용해 가장 친구의 친구의 친구의... 인 관계를 구한다. 각 친구 관계를 입력받아 양방향 간선 형태로 연결해 준다. 각 회원의 관계 중 가장 먼 사람과의 관계가 각 회원의 점수이고, 만약 연결되지 않은 사람이 있다면 이 사람은 후보가 될 수 없다. 이제 모든 회원들의 점수 중 최솟값을 구하고 최소 점수를 가진 후보들을 구하면 된다.

 

 

코드

#include <bits/stdc++.h>
using namespace std;
#define INF 1e9

int main() {
  ios::sync_with_stdio(false);
  cin.tie(NULL);
  int N, dist[51][51];
  cin >> N;
  // dist 배열 초기화
  for (int i = 1; i <= N; i++)
    for (int j = 1; j <= N; j++)
      dist[i][j] = i == j ? 0 : INF;
  // 간선 입력
  while (1) {
    int a, b;
    cin >> a >> b;
    if (a == -1 && b == -1)
      break;
    dist[a][b] = 1;
    dist[b][a] = 1;
  }
  // 플로이드 워셜
  for (int k = 1; k <= N; k++)
    for (int i = 1; i <= N; i++)
      for (int j = 1; j <= N; j++)
        dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
  // 각 멤버의 점수와 점수의 최솟값
  vector<int> member(N + 1), ans;
  int M = INF;
  for (int i = 1; i <= N; i++) {
    for (int j = 1; j <= N; j++) {
      // 각 회원의 친구 중 가장 거리가 먼 사람
      int tmp = *max_element(dist[i] + 1, dist[i] + N + 1);
      // 모두 연결되어 있지 않은 경우
      if (tmp == INF)
        continue;
      if (tmp < M)
        M = tmp;
      member[i] = tmp;
    }
  }
  cout << M << ' ';
  // 점수가 최소인 사람의 수 구하기, 그 사람들 번호 구하기
  int cnt = 0;
  for (int i = 1; i <= N; i++)
    if (member[i] == M) {
      cnt++;
      ans.push_back(i);
    }
  cout << cnt << '\n';
  for (int i : ans)
    cout << i << ' ';
  cout << '\n';
  return 0;
}
728x90
반응형