일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- 구현
- 이분탐색
- 서로소 집합
- boj 1464
- 뒤집기 3
- 브루트포스
- disjoint set
- 분할정복
- DP
- 패스트캠퍼스
- 그래프 이론
- 1939백준
- bfs
- parametric search
- union find
- 그래프 탐색
- 결정 문제
- 백준 뒤집기 3
- 최장증가수열
- 그래프탐색
- 깊이 우선 탐색
- 2493 백준
- 재귀
- 결정문제
- 백준 1464
- 그래프이론
- 이분 탐색
- 최장길이바이토닉수열
- 비트마스킹
- Lis
Archives
- Today
- Total
알고리즘 문제풀이
[BOJ] 1058번 - 친구 본문
백준 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
출처
알고리즘 분류
- 그래프 이론
- 그래프 탐색
- 브루트포스 알고리즘
- 깊이 우선 탐색
접근 방법
모든 사람들에 대해 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