https://www.acmicpc.net/problem/1325
1325번: 효율적인 해킹
첫째 줄에, N과 M이 들어온다. N은 10,000보다 작거나 같은 자연수, M은 100,000보다 작거나 같은 자연수이다. 둘째 줄부터 M개의 줄에 신뢰하는 관계가 A B와 같은 형식으로 들어오며, "A가 B를 신뢰한
www.acmicpc.net
최종 코드
GitHub - hwayeon351/BEAKJOON-Algorithms: 백준 알고리즘 소스 코드 모음
백준 알고리즘 소스 코드 모음. Contribute to hwayeon351/BEAKJOON-Algorithms development by creating an account on GitHub.
github.com
//
// main.cpp
// BJ1325_bfs
//
// Created by Hwayeon on 2021/08/18.
//
#include <iostream>
#include <string.h>
#include <vector>
#include <queue>
using namespace std;
int N, M;
int counts[10001] = {0, };
int visit[10001] = {0, };
vector<int> graph[10001];
int max_cnt = 0;
void bfs(int s){
queue<int> q;
q.push(s);
visit[s] = 1;
counts[s]++;
while(!q.empty()){
int nv = q.front();
q.pop();
for(int i=0; i<graph[nv].size(); i++){
if(!visit[graph[nv][i]]){
counts[s]++;
visit[graph[nv][i]] = 1;
q.push(graph[nv][i]);
}
}
}
}
int main(int argc, const char * argv[]) {
cin >> N >> M;
for(int i=0; i<M; i++){
int v1, v2;
cin >> v1 >> v2;
graph[v2].push_back(v1);
}
for(int i=1; i<=N; i++){
memset(visit, 0, sizeof(visit));
bfs(i);
if(counts[i] > max_cnt) max_cnt = counts[i];
}
for(int i=1; i<=N; i++){
if(counts[i] == max_cnt) cout << i << " ";
}
return 0;
}
GitHub - hwayeon351/BEAKJOON-Algorithms: 백준 알고리즘 소스 코드 모음
백준 알고리즘 소스 코드 모음. Contribute to hwayeon351/BEAKJOON-Algorithms development by creating an account on GitHub.
github.com
import sys
from collections import deque, defaultdict
N, M = map(int, sys.stdin.readline().split())
graph = defaultdict(list)
for _ in range(M):
v1, v2 = map(int, sys.stdin.readline().split())
graph[v2].append(v1)
def bfs(s):
q = deque()
q.append(s)
visit = [0] * (N+1)
visit[s] = 1
counts[s] = 1
while q:
now_v = q.popleft()
for nv in graph[now_v]:
if not visit[nv]:
visit[nv] = 1
counts[s] += 1
q.append(nv)
max_cnt = 0
counts = [0]*(N+1)
for i in range(1, N+1):
bfs(i)
if counts[i] > max_cnt: max_cnt = counts[i]
for i, cnt in enumerate(counts):
if cnt == max_cnt:
print(i, end=' ')
GitHub - hwayeon351/BEAKJOON-Algorithms: 백준 알고리즘 소스 코드 모음
백준 알고리즘 소스 코드 모음. Contribute to hwayeon351/BEAKJOON-Algorithms development by creating an account on GitHub.
github.com
//
// main.cpp
// BJ1325
//
// Created by Hwayeon on 2021/08/18.
//
#include <iostream>
#include <vector>
#include <string.h>
using namespace std;
int N, M;
vector<int> graph[10001];
int counts[10001] = {0, };
int visit[10001] = {0, };
int max_cnt = 0;
void dfs(int v, int s){
for(int i=0; i<graph[v].size(); i++){
if(!visit[graph[v][i]]){
visit[graph[v][i]] = 1;
counts[s]++;
dfs(graph[v][i], s);
}
}
}
int main(int argc, const char * argv[]) {
cin >> N >> M;
for(int i=0; i<M; i++){
int v1, v2;
cin >> v1 >> v2;
graph[v2].push_back(v1);
}
for(int i=1; i<=N; i++){
memset(visit, 0, sizeof(visit));
visit[i] = 1;
dfs(i, i);
if(counts[i] > max_cnt) max_cnt = counts[i];
}
for(int i=1; i<=N; i++){
if(counts[i] == max_cnt) cout << i << " ";
}
cout << endl;
return 0;
}
풀이 과정
풀이 시간 23분
방향 그래프의 탐색 문제이다. 인접 리스트 방식으로 방향 그래프를 표현한 다음, 각 컴퓨터 번호를 시작 노드로 하여 깊이 우선 탐색 DFS 또는 너비 우선 탐색 BFS을 하면 된다.
Python3로 채점을 하면 DFS와 BFS 구현 모두 시간초과가 났다.
이론상 DFS와 BFS의 시간복잡도는 O(V+E)이다.
각각의 컴퓨터로부터 완전 탐색을 진행해야 하니 시간복잡도는 O(V(V+E))이다.
문제에서 N은 최대 10,000이고, M은 100,000이니, 총 1,100,000,000번의 연산이 소요되니 10초 이상이 걸린다.
따라서, 시간초과가 날 것이라 생각한다.
실제로 Pypy로 돌리니 재귀를 사용한 DFS는 메모리 초과가 나고 BFS는 16200ms로 통과가 됐다.
하지만 문제의 제한 시간은 5초이고 사실상16200ms는 16초가 넘은 시간인데 시간초과가 나야하는데 왜 통과가 되었는지는 의문이다.
또한, DFS에서 메모리 초과가 나길래 visit 배열을 전역변수로 선언하고 초기화하는 방법으로 수정해 봤는데도 여전히 메모리 초과가 난다.
왜일까..?
#메모리초과 코드
import sys
from collections import defaultdict
sys.setrecursionlimit(500000000)
global m_cnt
def dfs(v, s):
for nv in graph[v]:
if visit[nv] == 0:
visit[nv] = 1
counts[s] += 1
dfs(nv, s)
N, M = map(int, sys.stdin.readline().split())
graph = defaultdict(list)
for _ in range(M):
v1, v2 = map(int, sys.stdin.readline().split())
graph[v2].append(v1)
counts = [0]*(N+1)
visit = [0]*(N+1)
max_cnt = 0
for i in range(1, N+1):
visit = [0]*(N+1)
visit[i] = 1
dfs(i, i)
if counts[i] > max_cnt:
max_cnt = counts[i]
for i, cnt in enumerate(counts):
if cnt == max_cnt:
print(i, end=" ")
C++의 속도가 궁금해서 C++로도 문제를 풀어봤다.
C++로는 DFS와 BFS 코드 모두 통과가 되었다.
BFS 코드는 2920ms, DFS 코드는 3520ms의 시간이 소요되었다.
확실히 C++이 파이썬보다 속도측에서 빠르다는 것을 실감했다.
'코테 노트 > 백준' 카테고리의 다른 글
백준 16173 점프왕 쩰리 (Small) Python3 (0) | 2021.08.19 |
---|---|
백준 17142 연구소 3 C++ (0) | 2021.08.18 |
백준 11659 구간 합 구하기 4 Python3 (0) | 2021.08.18 |
백준 11725 트리의 부모 찾기 Python3 (0) | 2021.08.18 |
백준 17140 이차원 배열과 연산 C++ (0) | 2021.08.17 |