알고리즘 문제풀이

[BOJ] 1058번 - 친구 본문

자료구조 + 알고리즘/[BOJ]

[BOJ] 1058번 - 친구

JoonDev 2020. 11. 20. 21:50

백준 1058번-친구

시간제한 메모리 제한 제출 정답 맞은 사람 정답 비율
2 초 128 MB 3670 1323 1097 37.659%

문제

지민이는 세계에서 가장 유명한 사람이 누구인지 궁금해졌다. 가장 유명한 사람을 구하는 방법은 각 사람의 2-친구를 구하면 된다. 어떤 사람 A가 또다른 사람 B의 2-친구가 되기 위해선, 두 사람이 친구이거나, A와 친구이고, B와 친구인 C가 존재해야 된다. 여기서 가장 유명한 사람은 2-친구의 수가 가장 많은 사람이다. 가장 유명한 사람의 2-친구의 수를 출력하는 프로그램을 작성하시오.

A와 B가 친구면, B와 A도 친구이고, A와 A는 친구가 아니다.

입력

첫째 줄에 사람의 수 N이 주어진다. N은 50보다 작거나 같은 자연수이다. 둘째 줄부터 N개의 줄에 각 사람이 친구이면 Y, 아니면 N이 주어진다. (예제를 참고)

출력

첫째 줄에 가장 유명한 사람의 2-친구의 수를 출력한다.

예제 입력 1

3
NYY
YNY
YYN

예제 출력 1

2

 

 

출처

www.acmicpc.net/problem/1058

알고리즘 분류

  • 그래프 이론
  • 그래프 탐색
  • 브루트포스 알고리즘
  • 깊이 우선 탐색

접근 방법

모든 사람들에 대해 2-친구수를 구한 다음, 2-친구수의 최댓값을 모두 찾으면 된다. (Brute-Force)

사람 A와 B가 친구 관계에 있을 때 정점의 weight 를 1로 가정, 친구 관계가 아닐 경우 INF로 두어서

모든 정점 쌍들의 최단거리를 구하는 "플로이드 와샬" 알고리즘을 이용하여 풀이하였다.

시간복잡도는 $O(N^3)$가 되겠다.

소스 코드

#include <bits/stdc++.h>
using namespace std;
int main(void){
    int N;
    cin >> N;

    bool areFriends[51][51] = {false, };
    for(int i=0; i<N; i++){
        string in;
        cin >> in;
        for(int j=0; j<in.size(); j++){
            if(in[j] == 'Y') areFriends[i][j] = true;
            else areFriends[i][j] = false;
        }
    }

    // 플로이드 와샬 이용
    // 각 정점간의 거리가 2이하인 모든 쌍을 모두 조사
    int dp[51][51] ;
    for(int i=0; i<N; i++){
        for(int j=0; j<N; j++)
            dp[i][j] = 1e9;
    }

    for(int i=0; i<N; i++){
        for(int j=0; j<N; j++){
            if( areFriends[i][j] ){
                dp[i][j] = 1;
            }
            if( i == j )
                dp[i][j] = 0;
        }
    }

    for(int k=0; k<N; k++){
        for(int i=0; i<N; i++){
            for(int j=0; j<N; j++){
                if( dp[i][j] > dp[i][k] + dp[k][j] )
                    dp[i][j] = dp[i][k] + dp[k][j] ;
            }
        }
    }
    int ans = 0;
    for(int i=0; i<N; i++){
        int cnt = 0;
        for(int j=0; j<N; j++){
            if( i == j ) continue;
            if( dp[i][j] <= 2 ) cnt += 1;
        }
        if( cnt > ans ) ans = cnt;
    }
    cout << ans;
    return 0;
}

'자료구조 + 알고리즘 > [BOJ]' 카테고리의 다른 글

[BOJ] 2493번 - 탑  (0) 2020.11.22
[BOJ] 1706번 - 크로스워드  (0) 2020.11.21
[BOJ] 1939번 - 중량제한  (0) 2020.11.19
[BOJ] 1360번 - 되돌리기  (0) 2020.11.18
[BOJ] 1300번 - K번째 수  (0) 2020.11.16
Comments