레야몬
[C++] 1005번 ACM Craft - DP, 위상 정렬, DFS 본문
#include <iostream>
#include <vector>
#include <queue>
#include <string.h>
#define MAX_BUILDING 1001
#define MAX_ROUTE 100001
using namespace std;
int T, N, K; //테스트케이스의 개수 T, 건물의 개수 N, 건설 순서 규칙의 개수 K
int t[MAX_BUILDING]; //건설에 걸리는 시간
vector<int> r[MAX_ROUTE]; //건설 작업 루트
int inDegree[MAX_BUILDING]; //진입 차수
int res[MAX_BUILDING]; //위상 정렬 결과
int dis[MAX_BUILDING]; //앞에서부터 건설하는데 까지 걸리는 시간
void topologySort() //위상 정렬
{
queue<int> q;
for(int i=1; i<=N; i++) {
if(!inDegree[i]) q.push(i); //진입 차수가 0인 것을 큐에 삽입
}
for(int i=0; i<N; i++) {
int x = q.front(); q.pop();
res[i]=x;
for(int j=0; j<r[x].size(); j++) {
int y = r[x][j]; //새롭게 진입 차수가 0이 된 정점 큐에 삽입
if(!(--inDegree[y])) q.push(y);
}
}
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(NULL); cout.tie(NULL);
cin >> T;
for(int i=0; i<T; i++) {
for(int j=0; j<=N; j++)
r[j].clear(); //배열, 벡터 초기화
memset(dis, 0, (N+1)*sizeof(int));
cin >> N >> K;
for(int j=1; j<=N; j++)
cin >> t[j];
int X, Y; //X->Y로 건설 가능
for(int j=0; j<K; j++) {
cin >> X >> Y;
r[X].push_back(Y);
inDegree[Y]++; //진입 차수 1+
}
int W; //마지막 건설 건물
cin >> W;
topologySort(); //위상 정렬
for(int j=0; j<N; j++) {
for(int k=0; k<r[res[j]].size(); k++) {
int pre = res[j];
int next = r[res[j]][k];
if(t[pre] + dis[pre] > dis[next]) //현재 이동거리가 다음 목표까지의 거리보다 크면 갱신
dis[next]=t[pre]+dis[pre];
}
}
cout << dis[W]+t[W] << '\n';
}
return 0;
}
위상정렬이라는 게 처음 나와서 새로 공부했다. 쉬었다가 다시 공부하려니까 백터 매소드도 기억이 안나서 복습했는데 아무튼 내가 이 문제를 풀면서 찾아봤던 사이트를 아래에 적어놨다.
나는 위상정렬로 풀어 160ms가 나왔는데 다른 사람의 코드를 보니까 위상 정렬이 아니라 BFS로 풀어서 더 빨리 푼 경우도 있었다. 위상 정렬을 썼을 때에는 DP를 한 번더 써줘야됬었는데 BFS로 푸니까 바로 나와서 조금 신기하기는 했다.
<위상 정렬>
https://m.blog.naver.com/ndb796/221236874984
25. 위상 정렬(Topology Sort)
위상 정렬(Topology Sort)은 '순서가 정해져있는 작업'을 차례로 수행해야 할 때 그 순서를 결정해주기 ...
blog.naver.com
<vector method>
https://blockdmask.tistory.com/70
[C++] vector container 정리 및 사용법
안녕하세요. BlockDMask 입니다. 오늘은 C++ STL의 sequence container 중에 정말 자주 쓰는 vector에 대해서 알아보겠습니다. <목차> 1) vector container 란? 2) vector의 사용 3) vector의 생성자와 연산..
blockdmask.tistory.com
<BFS로 푼 코드(풀어야 볼 수 있습니다.>
https://www.acmicpc.net/source/18541227
로그인
www.acmicpc.net
※현재 고등학교 등교중인 학생입니다. 이제 알고리즘을 본격적으로 공부하기 시작해서 아직 초보입니다. 혹시 제가 잘못 알고있는 점이나 더 좋은 풀이 방법이 있어 댓글에 남겨주시면 감사히 하나하나 열심히 읽어보겠습니다. 좋아요, 단순한 댓글 한마디라도 저에겐 큰 힘이 됩니다! 감사합니다.
'알고리즘 > 백준' 카테고리의 다른 글
[C++] 1208번 부분수열의 합 2 - 중간에서 만나기 (0) | 2022.09.21 |
---|---|
[C++] 1202번 보석 도둑 - 그리디, 정렬, 우선순위 큐 (0) | 2022.09.20 |
[C++] 1197번 최소 스패닝 트리 - 최소 스패닝 트리, Union-Find (2) | 2022.09.07 |
[C++] 15654번 N과 M (5) - 백트래킹 (0) | 2022.09.06 |
[C++] 15650번 N과 M (2) - 백트래킹 (0) | 2022.09.06 |