[c/c++] 백준 2606 (Silver 3)

은동·2023년 2월 11일
0

Baekjoon

목록 보기
22/49

🔨 문제

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

1번 컴퓨터가 바이러스에 걸렸을 때 1번 컴퓨터를 통해 바이러스에 감염되는 컴퓨터의 수를 출력


🔨 해결방법

DFS - https://m42-orion.tistory.com/m/63
BFS - https://m42-orion.tistory.com/m/64
차이점 - https://velog.io/@lucky-korma/DFS-BFS%EC%9D%98-%EC%84%A4%EB%AA%85-%EC%B0%A8%EC%9D%B4%EC%A0%90

위의 블로그에서 도움을 많이 받았다.

  • dfs?
    그래프 전체를 탐색하는 방법
    하나의 가지(branch)를 모두 탐색한 이후에 다음 branch로 이동

    stack 또는 재귀함수로 구현

  • 특징
    정점 방문 시, 정점 방문 여부를 검사하지 않으면 무한 루프에 빠질 수 있기 때문에 반드시 방문 여부를 검색해야 한다.

    bfs보다 메모리를 아낄 수 있다.

    얻은 결과가 최단 경로라는 보장이 없다.

  • bfs?
    그래프 전체를 탐색하는 방법
    현재 정점으로부터 가까운 정점들을 먼저 방문

    queue를 이용하여 구현

  • 특징
    queue에 다음에 탐색할 정점들을 push하고 pop하는 과정을 거치기 때문에, dfs에 비해서 메모리가 더 필요하다.

    얻은 결과가 최단 경로임을 보장한다.

    목표 노드의 깊이 가 얕은 경우 dfs보다 더 빠르게 해답을 구할 수 있다.


자세한 실행 방식은 주석으로 확인


🔨 코드

DFS 이용

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

vector<vector<int>> graph;	//인접 리스트
//이중 vector 를 사용함으로써 필요한 메모리만 할당해서 사용할 수 있음
vector<bool> infected;	//정점 방문 여부 저장
queue <int> q;

void dfs(int start){
	infected[start] = true;

	for (int i = 0; i < graph[start].size(); i++) {
		int next = graph[start][i];
		if (!infected[next]) {
			dfs(next);	// 재귀함수
		}
	}
}


int main() {
	cin.tie(NULL);
	cout.tie(NULL);
	ios::sync_with_stdio(false);

	int n, line;	//정점의 개수, 간선의 개수
	cin >> n >> line;
	graph.assign(n + 1, vector<int>(0, 0));	//assign 함수를 통해서 vector<int>를 n+1개 할당
	infected.assign(n + 1, false); // 노드는 1~n, 모두 false로 초기화
	

	for (int i = 0; i < line; i++) {	//간선 연결
		int n1, n2;
		cin >> n1 >> n2;
		graph[n1].push_back(n2);
		graph[n2].push_back(n1);
	}
	
	dfs(1);	// bfs 시작 노드 1
	int total = 0;
	for (int i = 2; i <= n; i++) {	//이미 1번은 감염
		if (infected[i]) total++;
	}
	cout << total;
	
	return 0;
}

BFS 이용

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

vector<vector<int>> graph;	//인접 리스트
//이중 vector 를 사용함으로써 필요한 메모리만 할당해서 사용할 수 있
vector<bool> infected;	//정점 방문 여부 저장
queue <int> q;

void bfs(int start) {
	q.push(start);
	infected[start] = true;	// 시작 노드 방문 처리

	while (!q.empty()) {
		int cur = q.front();	// 큐에서 제일 앞에 있는 값을 꺼냄
		q.pop();
		for (int i = 0; i < graph[cur].size(); i++) {	//현재 노드의 인접한 노드들을 반복문을 통해 접근
			int next = graph[cur][i];	
			if (!infected[next]) {	// 감염됐는지 확인하고, 방문하지 않은 경우에만 노드를 큐에 삽입 -> 방문처리
				q.push(next);
				infected[next] = true;
			}
			
		}
	}
}

int main() {
	cin.tie(NULL);
	cout.tie(NULL);
	ios::sync_with_stdio(false);

	int n, line;	//정점의 개수, 간선의 개수
	cin >> n >> line;
	graph.assign(n + 1, vector<int>(0, 0));	//assign 함수를 통해서 vector<int>를 n+1개 할당
	infected.assign(n + 1, false); // 노드는 1~n, 모두 false로 초기화
	

	for (int i = 0; i < line; i++) {	//간선 연결
		int n1, n2;
		cin >> n1 >> n2;
		graph[n1].push_back(n2);
		graph[n2].push_back(n1);
	}
	
	bfs(1);	// bfs 시작 노드 1
	int total = 0;
	for (int i = 2; i <= n; i++) {	//이미 1번은 감염
		if (infected[i]) total++;
	}
	cout << total;
	
	return 0;
}
profile
자자 선수입장~

0개의 댓글