본문 바로가기
Programming/BOJ

[C/C++] 백준 #2056 작업(위상정렬)

by 작은별하나 2023. 3. 23.
반응형

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

 

2056번: 작업

수행해야 할 작업 N개 (3 ≤ N ≤ 10000)가 있다. 각각의 작업마다 걸리는 시간(1 ≤ 시간 ≤ 100)이 정수로 주어진다. 몇몇 작업들 사이에는 선행 관계라는 게 있어서, 어떤 작업을 수행하기 위해

www.acmicpc.net

 

이번 문제는 선행작업과 후행작업이 있을 때, 전체 작업시간이 얼마나 걸릴 것인지 판단하는 것입니다.  소프트웨어 공학에서 자주 발생하는 일입니다.  소프트웨어 공학에서도 선행작업과 후행작업이 있는 경우 작업 인력을 무한정 투입할 경우 마칠 수 있는 최소 시간을 구하게 됩니다.  

 

이와 같이 작업의 선후가 있는 경우에 위상정렬을 사용하게 됩니다.  위상절렬은 작업의 선후에 따라서 정렬을 하는 것이지만, 이 문제에서는 작업시간을 최종적으로 결정해야 합니다.  위상정렬과 이 문제는 크게 다르지 않습니다.  단지 작업시간을 후행작업에게 알려주는 추가 작업만 더 해주시면 됩니다.

 

위상정렬을 이용하는 문제들입니다.

https://sdev.tistory.com/894

 

[C/C++] 백준 #1766 문제집(위상정렬)

이번 문제는 일을 처리하는데 있어서 우선순위가 주어진 경우 그것을 해결하는 방법입니다. 1. N개의 문제는 반드시 풀어야 한다. 2. 먼저 푸는 것이 좋은 문제가 있는 경우에는 더 쉬운 문제를

sdev.tistory.com

 

https://sdev.tistory.com/682

 

#1516 게임 개발

게임 개발 문제는 위상정렬(Topology sort)를 사용해서 풀 수 있는 문제입니다. https://www.acmicpc.net/problem/1516 1516번: 게임 개발 첫째 줄에 건물의 종류 수 N(1 ≤ N ≤ 500)이 주어진다. 다음 N개의 줄에는

sdev.tistory.com

 

https://sdev.tistory.com/597

 

#79 암호 알아내기(Topology Sort)

이번문제는 난이도 5%로 아주 쉬운 문제로 분류되어 있습니다. 아마 단순무식(Brute Force) 방법으로도 풀리는 문제로 분류되어서인 듯 합니다. 숫자가 많지 않기 때문에 단순하게 조건에 맞도록 배

sdev.tistory.com

 

위상정렬(Topological Sort)은 이름과는 달리 구현 방법이 간단한 알고리즘입니다.

 

Topological Sort

 

위상 정렬은 선후 관계를 나타내는 방향 그래프(DAG)로 구성되어 있습니다.  인입간선은 해당 작업의 선행 작업이 있다는 의미이고, 진출간선은 후행 작업이 있다는 의미입니다.  인입간선이 하나도 없다는 것은 해당 작업은 지금 바로 실행할 수 있다는 의미를 가집니다.  그래서 인입간선이 하나도 없는 노드들을 이용해서 해당 노드의 진출간선을 제거하면서 알고리즘이 반복되면 됩니다.

 

다음은 제가 작성한 소스입니다.

//------------------------------------------------
//    baekjoon #2056 - Job
//        - by Aubrey Choi
//        - created at 2019-07-18
//------------------------------------------------
#include <stdio.h>

struct Node { int s, value, count; int link[100]; };

int main()
{
    int n, max = 0, i, j, m;
    static Node node[10001];
    scanf("%d", &n);
    for(i = 1; i <= n; i++)
    {
        scanf("%d%d", &node[i].value,&node[i].count);
        for(j=0; j<node[i].count; j++) scanf("%d", &node[i].link[j]);
    }
    for(i = 1; i <= n; i++)
    {
        for(j=0, m=0; j<node[i].count; j++)
        {
            int f = node[i].link[j];
            if(node[f].s > m) m = node[f].s;
        }
        node[i].s = m + node[i].value;
        if(node[i].s > max) max = node[i].s;
    }
    printf("%d\n", max);
}
728x90

댓글