https://www.acmicpc.net/problem/1005
- 그림이 곧 힌트입니다.(단방향 그래프 & acyclic) -> 위상 정렬
- 이전의 건물이 모두 완성되어야 건설을 시작할 수 있음 -> 위상 정렬
위상 정렬은 다음과 같은 순서로 진행이 됩니다.
1. 자신을 가리키지 않는 점을 확인합니다.
indeg 배열이 0이 될 때에 비로소 제한이 풀리는 것을 염두하지 않고 무작정 push 후 비교를 하면 중첩비교가 꽤나 많이 됩니다. 이 점을 감안하고 풀지 않을 시 메모리 초과가 발생하니 주의하시기 바랍니다.(경험담)
if (--indeg[nxt] == 0) {
q.push(nxt);
}
#include<iostream>
#include<queue>
using namespace std;
int t, n, m, w;
int indeg[1001], cost[1001], dist[1001];
vector<int> v[1001];
void input() {
cin >> n >> m;
int a, b;
for (int i = 1; i <= n; ++i) {
cin >> cost[i];
indeg[i] = 0;
dist[i] = cost[i];
v[i].clear();
}
for (int i = 0; i < m; ++i) {
cin >> a >> b;
v[a].push_back(b);
++indeg[b];
}
cin >> w;
}
void solution() {
input();
queue<int> q;
for (int i = 1; i <= n; ++i) {
if (indeg[i] == 0) {
q.push(i);
}
}
while (!q.empty()) {
int cur = q.front(); q.pop();
for (int nxt : v[cur]) {
if (--indeg[nxt] == 0) {
q.push(nxt);
}
dist[nxt] = max(dist[nxt], dist[cur] + cost[nxt]);
}
}
cout << dist[w] << '\n';
}
int main() {
cin.tie(0), cout.tie(0);
ios_base::sync_with_stdio(0);
int t;
cin >> t;
for (int i = 0; i < t; ++i) {
solution();
}
return 0;
}