포스트

백준 10282. 해킹

해킹

다익스트라 문제 기본 문제

여러 테스트케이스를 다루면서 언제 어떻게 초기화 해야하는지를 알 수 있는 문제

1. 간단 설명


image

최단경로를 풀어봤다면 조금 응용하면 된다

2. 예시


1
2
3
4
5
6
7
8
2
3 2 2
2 1 5
3 2 5
3 3 1
2 1 2
3 1 8
3 2 4

TC 2개가 주어진다

TC1)

image

3 2 2 (컴퓨터 3대, 의존성 개수 2개, 해킹당한 컴퓨터 번호 2)

2 1 5 : 2번 컴퓨터는 1번에 의존하며, 5초가 걸림

3 2 5 : 3번이 2번에 의존, 5초 걸림

결과 : 5초 뒤 2, 3 감염된다

TC2)

image

3 3 1(컴퓨터 3대, 의존성 개수 3개, 해킹 당한 컴퓨터 번호 1)

2->1 2초

3->1 8초

3->2 4초

결과 : 6초 뒤 1,2,3 모두 감염된다

3번은 2번을 거쳐 감염되는게 1번에서 바로 감염되는것보다 빠르다(2초 + 4초 vs 8초)

주의사항

번역이 햇갈릴 수 있는데 그래프 방향에 주의해야한다

a가 b에 의존할 때, s초가 걸린다 b->a (s초)

3. 알고리즘


1
2
3
4
5
6
1. TC 개수 입력받기
2. 테스트 케이스가 종료될 때 까지 반복한다
	2-1. 각 테스트케이스별로 n, d, c 입력받기
	2-2. 변수 초기화 진행
	2-3. 바이러스 시작 컴퓨터로부터 다익스트라 수행
	2-4. 다익스트라 종료 후, 감염된 컴퓨터 대수와 최종 시간 확인 후 출력

필요 변수

  • 테스트 케이스 개수 int T
  • 컴퓨터개수, 의존성 개수, 해킹당한 컴퓨터 번호 int n, d, c (1 ≤ n ≤ 10,000, 1 ≤ d ≤ 100,000, 1 ≤ c ≤ n)
  • 의존성 정보 int a, b, s (1 ≤ a, b ≤ n, a ≠ b, 0 ≤ s ≤ 1,000)
  • 의존성 정보 맵 vector< vector<pair<int, int» > map;
  • 다익스트라 정보
    • 걸린 시간을 기록할 배열 vector<int> d(N+1) 최대 10,000,000이므로 int로 처리 가능
  • 감염된 컴퓨터 정보 bool corrupted[N+1]

4. 소스코드


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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#include <iostream>
#include <queue>
#include <vector>

using namespace std;

int TC;
int n, d, c;
int a, b, s;
vector< vector<pair<int, int>> > map;
vector<int> dist;
vector<bool> corrupted;

void dijkstra(int start) {
	
	dist[start] = 0;
	priority_queue<pair<int, int>> pq;
	pq.push({ start, 0 });
	corrupted[start] = true;

	while (!pq.empty()) {
		int now = pq.top().first;
		int now_dist = -pq.top().second; 
		pq.pop();

		// 현재 노드와 연결된 노드 찾기
		for (int t = 0; t < map[now].size(); t++) {
			int next = map[now][t].first;
			int next_dist = map[now][t].second + now_dist;

			// 구한 경로가 저장된 경로보다 짧다면
			if (next_dist < dist[next]) {
				dist[next] = next_dist;
				corrupted[next] = true;
				pq.push({ next, -next_dist });
			}
		}
	}
}

void Input() {
	cin >> n >> d >> c;

	map.clear();  map.resize(n + 1);
	for (int i = 0; i < d; i++) {
		cin >> a >> b >> s;
		map[b].push_back({ a, s });
	}

	dist.clear(); dist.resize(n + 1);
	for (int i = 0; i <= n; i++) {
		dist[i] = 21e8;
	}

	corrupted.clear(); corrupted.resize(n + 1);
}

void Output() {
	int res = 0, time = 0;
	for (int i = 1; i <= n; i++) {
		if (corrupted[i]) {
			res++;
			if (time < dist[i]) {
				time = dist[i];
			}
		}
	}
	cout << res << ' ' << time << '\n';
}

int main() {
	freopen_s(new FILE*, "input.txt", "r", stdin);

	cin >> TC;

	while (TC--) {
		Input();
		dijkstra(c);
		Output();
	}

	return 0;
}

다익스트라 구현을 위해 연습한 문제

우선순위큐를 사용해서 정렬 시, 음수를 사용해서 최소값을 먼저 뽑아냈다

이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.