https://www.acmicpc.net/problem/1005
1005번: ACM Craft
첫째 줄에는 테스트케이스의 개수 T가 주어진다. 각 테스트 케이스는 다음과 같이 주어진다. 첫째 줄에 건물의 개수 N과 건물간의 건설순서 규칙의 총 개수 K이 주어진다. (건물의 번호는 1번부
www.acmicpc.net
문제설명
위상정렬로도 풀 수있고 dfs+dp로 풀 수도 있는 문제인데 저는 후자로 풀었습니다.
예제처럼 입력이 들어오면 위 그림과 같이 트리를 만들었고 시작은 4번건물에서 시작을 했습니다.
4번에서 dfs를 돌면 4->2->1->3의 순서로 순회를 돌겁니다.
dfs(4)는 dfs(2)를 부르고 dfs(2)는 dfs(1)을 부르고 1이 끝이니 dfs(2)로 리턴 dfs(2)도 dfs(4)로 리턴 그 후
dfs(4)는 dfs(3)를 부르고 dfs(1)을 부르고 싶지만 이미 방문을 했으므로 종료할겁니다.
그리고 방문여부를 ans배열로 확인을 할 것 이고 ans[n]의 정의를 n번 건물을 만드는데 걸리는 시간이라고 정의를합니다.
이렇게 정의를 한 후에 4->2->1까지 dfs(4)로 다시 돌아온 후에 ans[4]에는 21 ans[2]에는 11 ans[1]에는 10 값이 들어있을겁니다.
그 후 dfs(4)까지 다시 돌아와서 dfs(3)을 호출할 것 이고 dfs(3)은 dfs(1)을 호출 할겁니다.
그런데 dfs(1)에서 ans[1]은 이미 값이 10으로 할당이 되어있으므로 그 값 10을 리턴하게하고 그러면 ans[3]에는 100+10=110이 들어갑니다.
dfs(4)에서 기존의 21과 새로운 110+10=120을 비교해서 120이 크므로 ans[4]의값은 21에서 120으로 바뀝니다.
이 값을 리턴하면 그것이 답이 됨.
단 0 ≤ Di ≤ 100,000라고 문제에 명시가 되어있기 때문에 ans를 처음에 이 범위에 해당하지 않는 -1으로 초기화했음.
코드
#include <iostream>
#include <algorithm>
#include <vector>
typedef long long int ll;
using namespace std;
void reset();
ll dfs(ll n);
ll ans[1001];
ll delay[1001];
vector <ll> v[1001];
int main(){
cout.tie(NULL);
cin.tie(NULL);
ios_base::sync_with_stdio(false);
ll t,n,k,x,y,w;
cin>>t;
while(t--)
{
reset();
cin>>n>>k;
for(ll i=1; i<=n; i++)
{
cin>>delay[i];
}
for(ll i=1; i<=k; i++)
{
cin>>x>>y;
v[y].push_back(x);
}
cin>>w;
cout<<dfs(w)<<"\n";
}
}
void reset(){
for(ll i=0; i<1001; i++)
{
ans[i]=-1;
delay[i]=0;
v[i].clear();
}
}
ll dfs(ll n){
if(v[n].size()==0)
{
ans[n]=delay[n];
return ans[n];
}
if(ans[n]!=-1)
{
return ans[n];
}
else
{
for(ll i=0; i<v[n].size(); i++)
{
ans[n]=max(ans[n],delay[n]+dfs(v[n][i]));
}
return ans[n];
}
}
'백준문제풀이' 카테고리의 다른 글
백준 문제 10942번 팰린드롬? 문제풀이 c++ (0) | 2022.03.20 |
---|---|
백준 문제 1334번 다음 팰린드롬 수 문제풀이 python (0) | 2022.03.20 |
백준 문제 1002번 터렛 문제풀이 c++ (0) | 2022.03.13 |
백준 문제 17387번 선분 교차 2 문제풀이 c++ (0) | 2022.03.13 |
백준 문제 17386번 선분 교차 1 문제풀이 c++ (0) | 2022.03.13 |