[c++] BOJ 1005 :: ACM Craft

๋‚œ์ด๋„ : ๊ณจ๋“œ 3

๊ฑธ๋ฆฐ ์‹œ๊ฐ„ : 1์‹œ๊ฐ„ ๋ฐ˜ ์ด์ƒ

 

๋ฌธ์ œ

ํ•ฉ๋ถ„ํ•ด ๋ฌธ์ œ ๋ฐ”๋กœ๊ฐ€๊ธฐ

 

1005๋ฒˆ: ACM Craft

์ฒซ์งธ ์ค„์—๋Š” ํ…Œ์ŠคํŠธ์ผ€์ด์Šค์˜ ๊ฐœ์ˆ˜ T๊ฐ€ ์ฃผ์–ด์ง„๋‹ค. ๊ฐ ํ…Œ์ŠคํŠธ ์ผ€์ด์Šค๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ฃผ์–ด์ง„๋‹ค. ์ฒซ์งธ ์ค„์— ๊ฑด๋ฌผ์˜ ๊ฐœ์ˆ˜ N ๊ณผ ๊ฑด๋ฌผ๊ฐ„์˜ ๊ฑด์„ค์ˆœ์„œ๊ทœ์น™์˜ ์ด ๊ฐœ์ˆ˜ K์ด ์ฃผ์–ด์ง„๋‹ค. (๊ฑด๋ฌผ์˜ ๋ฒˆํ˜ธ๋Š” 1๋ฒˆ๋ถ€

www.acmicpc.net

 

์„œ๊ธฐ 2012๋…„! ๋“œ๋””์–ด 2๋…„๊ฐ„ ์ˆ˜๋งŽ์€ ๊ตญ๋ฏผ๋“ค์„ ๊ธฐ๋‹ค๋ฆฌ๊ฒŒ ํ•œ ๊ฒŒ์ž„ ACM Craft (Association of Construction Manager Craft)๊ฐ€ ๋ฐœ๋งค๋˜์—ˆ๋‹ค.

์ด ๊ฒŒ์ž„์€ ์ง€๊ธˆ๊นŒ์ง€ ๋‚˜์˜จ ๊ฒŒ์ž„๋“ค๊ณผ๋Š” ๋‹ค๋ฅด๊ฒŒ ACMํฌ๋ž˜ํ”„ํŠธ๋Š” ๋‹ค์ด๋‚˜๋ฏนํ•œ ๊ฒŒ์ž„ ์ง„ํ–‰์„ ์œ„ํ•ด ๊ฑด๋ฌผ์„ ์ง“๋Š” ์ˆœ์„œ๊ฐ€ ์ •ํ•ด์ ธ ์žˆ์ง€ ์•Š๋‹ค. ์ฆ‰, ์ฒซ ๋ฒˆ์งธ ๊ฒŒ์ž„๊ณผ ๋‘ ๋ฒˆ์งธ ๊ฒŒ์ž„์ด ๊ฑด๋ฌผ์„ ์ง“๋Š” ์ˆœ์„œ๊ฐ€ ๋‹ค๋ฅผ ์ˆ˜๋„ ์žˆ๋‹ค. ๋งค ๊ฒŒ์ž„์‹œ์ž‘ ์‹œ ๊ฑด๋ฌผ์„ ์ง“๋Š” ์ˆœ์„œ๊ฐ€ ์ฃผ์–ด์ง„๋‹ค. ๋˜ํ•œ ๋ชจ๋“  ๊ฑด๋ฌผ์€ ๊ฐ๊ฐ ๊ฑด์„ค์„ ์‹œ์ž‘ํ•˜์—ฌ ์™„์„ฑ์ด ๋  ๋•Œ๊นŒ์ง€ Delay๊ฐ€ ์กด์žฌํ•œ๋‹ค.

img

์œ„์˜ ์˜ˆ์‹œ๋ฅผ ๋ณด์ž.

์ด๋ฒˆ ๊ฒŒ์ž„์—์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๊ฑด์„ค ์ˆœ์„œ ๊ทœ์น™์ด ์ฃผ์–ด์กŒ๋‹ค. 1๋ฒˆ ๊ฑด๋ฌผ์˜ ๊ฑด์„ค์ด ์™„๋ฃŒ๋œ๋‹ค๋ฉด 2๋ฒˆ๊ณผ 3๋ฒˆ์˜ ๊ฑด์„ค์„ ์‹œ์ž‘ํ• ์ˆ˜ ์žˆ๋‹ค. (๋™์‹œ์— ์ง„ํ–‰์ด ๊ฐ€๋Šฅํ•˜๋‹ค) ๊ทธ๋ฆฌ๊ณ  4๋ฒˆ ๊ฑด๋ฌผ์„ ์ง“๊ธฐ ์œ„ํ•ด์„œ๋Š” 2๋ฒˆ๊ณผ 3๋ฒˆ ๊ฑด๋ฌผ์ด ๋ชจ๋‘ ๊ฑด์„ค ์™„๋ฃŒ๋˜์–ด์•ผ์ง€๋งŒ 4๋ฒˆ๊ฑด๋ฌผ์˜ ๊ฑด์„ค์„ ์‹œ์ž‘ํ• ์ˆ˜ ์žˆ๋‹ค.

๋”ฐ๋ผ์„œ 4๋ฒˆ๊ฑด๋ฌผ์˜ ๊ฑด์„ค์„ ์™„๋ฃŒํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ์šฐ์„  ์ฒ˜์Œ 1๋ฒˆ ๊ฑด๋ฌผ์„ ๊ฑด์„คํ•˜๋Š”๋ฐ 10์ดˆ๊ฐ€ ์†Œ์š”๋œ๋‹ค. ๊ทธ๋ฆฌ๊ณ  2๋ฒˆ ๊ฑด๋ฌผ๊ณผ 3๋ฒˆ ๊ฑด๋ฌผ์„ ๋™์‹œ์— ๊ฑด์„คํ•˜๊ธฐ ์‹œ์ž‘ํ•˜๋ฉด 2๋ฒˆ์€ 1์ดˆ๋’ค์— ๊ฑด์„ค์ด ์™„๋ฃŒ๋˜์ง€๋งŒ ์•„์ง 3๋ฒˆ ๊ฑด๋ฌผ์ด ์™„๋ฃŒ๋˜์ง€ ์•Š์•˜์œผ๋ฏ€๋กœ 4๋ฒˆ ๊ฑด๋ฌผ์„ ๊ฑด์„คํ•  ์ˆ˜ ์—†๋‹ค. 3๋ฒˆ ๊ฑด๋ฌผ์ด ์™„์„ฑ๋˜๊ณ  ๋‚˜๋ฉด ๊ทธ๋•Œ 4๋ฒˆ ๊ฑด๋ฌผ์„ ์ง€์„์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ 4๋ฒˆ ๊ฑด๋ฌผ์ด ์™„์„ฑ๋˜๊ธฐ๊นŒ์ง€๋Š” ์ด 120์ดˆ๊ฐ€ ์†Œ์š”๋œ๋‹ค.

ํ”„๋กœ๊ฒŒ์ด๋จธ ์ตœ๋ฐฑ์ค€์€ ์• ์ธ๊ณผ์˜ ๋ฐ์ดํŠธ ๋น„์šฉ์„ ๋งˆ๋ จํ•˜๊ธฐ ์œ„ํ•ด ์„œ๊ฐ•๋Œ€ํ•™๊ต๋ฐฐ ACMํฌ๋ž˜ํ”„ํŠธ ๋Œ€ํšŒ์— ์ฐธ๊ฐ€ํ–ˆ๋‹ค! ์ตœ๋ฐฑ์ค€์€ ํ™”๋ คํ•œ ์ปจํŠธ๋กค ์‹ค๋ ฅ์„ ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋ชจ๋“  ๊ฒฝ๊ธฐ์—์„œ ํŠน์ • ๊ฑด๋ฌผ๋งŒ ์ง“๋Š”๋‹ค๋ฉด ๋ฌด์กฐ๊ฑด ๊ฒŒ์ž„์—์„œ ์ด๊ธธ ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋งค ๊ฒŒ์ž„๋งˆ๋‹ค ํŠน์ •๊ฑด๋ฌผ์„ ์ง“๊ธฐ ์œ„ํ•œ ์ˆœ์„œ๊ฐ€ ๋‹ฌ๋ผ์ง€๋ฏ€๋กœ ์ตœ๋ฐฑ์ค€์€ ์ขŒ์ ˆํ•˜๊ณ  ์žˆ์—ˆ๋‹ค. ๋ฐฑ์ค€์ด๋ฅผ ์œ„ํ•ด ํŠน์ •๊ฑด๋ฌผ์„ ๊ฐ€์žฅ ๋นจ๋ฆฌ ์ง€์„ ๋•Œ๊นŒ์ง€ ๊ฑธ๋ฆฌ๋Š” ์ตœ์†Œ์‹œ๊ฐ„์„ ์•Œ์•„๋‚ด๋Š” ํ”„๋กœ๊ทธ๋žจ์„ ์ž‘์„ฑํ•ด์ฃผ์ž.

 

ํ’€์ด

  • ์™„์ „ํƒ์ƒ‰์œผ๋กœ ์ƒ๊ฐํ•ด๋ณด์ž.
  • ์žฌ๊ท€๋กœ ๊ตฌํ˜„ํ•œ๋‹ค๊ณ  ํ–ˆ์„ ๋•Œ
    • ์ž‘์€ ๋ฌธ์ œ : (ํ˜„์žฌ๋…ธ๋“œ, ์‹œ๊ฐ„) => ์ตœ์†Œ์‹œ๊ฐ„
    • ์ข…๋ฃŒ ์กฐ๊ฑด
      • ๋”์ด์ƒ ๊ฐˆ ๋…ธ๋“œ๊ฐ€ ์—†์„ ๋•Œ
  • DP๋ฅผ ๋„ฃ๋Š”๋‹ค๊ณ  ํ–ˆ์„ ๋•Œ
    • ํ•ด๋‹น ๋…ธ๋“œ์—์„œ ๋๊นŒ์ง€ ๊ฑธ๋ฆฌ๋Š” ์‹œ๊ฐ„์„ ์ €์žฅ
    • ์–ด๋–ค ํ˜•ํƒœ๋กœ?
      • 2์ฐจ์› ๋ฐฐ์—ด์˜ ํ˜•ํƒœ!

 

์ฝ”๋“œ

<unordered_map ์ด์šฉ> => ํ‹€๋ฆผ

#include <unordered_map>
#include <vector>
#include <algorithm>
#include <iostream>
#include <cstring>

using namespace std;

unordered_map<int, vector<int>> flow;
int target; // ๊ฑด์„คํ•ด์•ผํ•  ๋…ธ๋“œ
int memo[100001];
int times[100001];

int getMaxTime(int node) {
    if (flow.find(node) == flow.end()) {
        // ๋”์ด์ƒ ๊ฐˆ ๊ณณ์ด ์—†์œผ๋ฉด
        return times[node - 1];
    }
    if (memo[node] != -1)
        return memo[node];

    vector<int> tmp = flow[node];
    int t = 0;
    for (int i = 0; i < tmp.size(); i++) {
        // ํ•„์š”ํ•œ ๋…ธ๋“œ๋“ค์˜ ์ตœ๋Œ€์‹œ๊ฐ„์„ ๊ตฌํ•˜๊ธฐ
        t = max(t, getMaxTime(tmp[i]));
    }
    t += times[node - 1];
    memo[node] = min(t, memo[node]); // memo๋Š” ์ตœ์†Œ๊ฐ’์œผ๋กœ ์œ ์ง€

    return t;
}

int main() {
    // ์ž…๋ ฅ ๋ฐ›๊ธฐ
    int N;
    cin >> N;

    while (N--) {
        int K, num;
        cin >> K >> num;

        memset(times, 0, sizeof(times));
        for (int i = 0; i < K; i++) {
            cin >> times[i];
        }

        flow.clear();
        for (int i = 0; i < num; i++) {
            // key: ์ดํ›„์— ๊ฑด์„ค๋˜์–ด์•ผ ํ•  ๋…ธ๋“œ, value : ์ด์ „์— ๊ฑด์„ค๋˜์–ด์•ผ ํ•  ๋…ธ๋“œ๋“ค
            int a, b;
            cin >> a >> b;
            if (flow.find(b) == flow.end()) {
                // ์—†์œผ๋ฉด ๋งŒ๋“ค๊ธฐ
                vector<int> tmp;
                flow[b] = tmp;
            }
            flow[b].push_back(a);
        }

        cin >> target;

        // ์ดˆ๊ธฐํ™”
        memset(memo, -1, sizeof(memo));

        cout << getMaxTime(target) << endl;
    }
    return 0;
}

 

<๋ฐฐ์—ด ์ด์šฉ>

#include <map>
#include <vector>
#include <algorithm>
#include <iostream>
#include <cstring>

using namespace std;

int N, K;
int flow[1001][1001];
int target; // ๊ฑด์„คํ•ด์•ผํ•  ๋…ธ๋“œ
int memo[1001];
int times[1001];

int getMaxTime(int node) {
    int &result = memo[node];
    if (result != -1)
        return result;

    int t = 0;
    for (int i = 1; i <= N; i++) {
        // ํ•„์š”ํ•œ ๋…ธ๋“œ๋“ค์˜ ์ตœ๋Œ€์‹œ๊ฐ„์„ ๊ตฌํ•˜๊ธฐ
        if (flow[i][node])
            t = max(t, getMaxTime(i));
    }

    return memo[node] = t + times[node];
}

int main(){
    // ์ž…๋ ฅ ๋ฐ›๊ธฐ
    int T;
    cin >> T;

    while (T--) {
        cin >> N >> K;

        memset(flow, 0, sizeof(flow));
        memset(memo, -1, sizeof(memo));

        for (int i = 1; i <= N; i++) {
            cin >> times[i];
        }
        for (int i = 0; i < K; i++) {
            // key: ์ดํ›„์— ๊ฑด์„ค๋˜์–ด์•ผ ํ•  ๋…ธ๋“œ, value : ์ด์ „์— ๊ฑด์„ค๋˜์–ด์•ผ ํ•  ๋…ธ๋“œ๋“ค
            int a, b;
            cin >> a >> b;
            flow[a][b] = 1;
        }

        cin >> target;

        cout << getMaxTime(target) << endl;
    }
    return 0;
}

 

์ฃผ์˜ํ•  ์ 

  • DP ์‹œ์— unordered_map์„ ์‚ฌ์šฉํ•˜๋ฉด push์™€ find์— ์‹œ๊ฐ„์ด ๋ฐฐ์—ด๋ณด๋‹ค ๋งŽ์ด ๊ฑธ๋ฆฌ๊ธฐ ๋•Œ๋ฌธ์—, ๊ณต๊ฐ„๋ณต์žก๋„๊ฐ€ ์ถฉ๋ถ„ํ•˜๋ฉด ๋ฐฐ์—ด์„ ์‚ฌ์šฉํ•˜์ž.
  • ์ถœ๋ ฅ์— ๋ฐ˜๋“œ์‹œ endl..

 

์œ„์ƒ์ •๋ ฌ๊ณผ์˜ ๋น„๊ต

  • ์œ„์ƒ์ •๋ ฌ๋กœ๋„ ํ’€ ์ˆ˜ ์žˆ๋‹ค.
    • ์œ„์ƒ์ •๋ ฌ์€ ์ž‘์—…์˜ ์ˆœ์„œ๋ฅผ ์ •ํ•ด์ฃผ๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ ์‚ฌ์ดํด์ด ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š” ๊ทธ๋ž˜ํ”„์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ์œ„์ƒ์ •๋ ฌ
  • ์œ„์ƒ์ •๋ ฌ์„ ์ด์šฉํ•œ ๋ฐฉ๋ฒ•
    • ๊ฐ ๊ฑด๋ฌผ์„ ์ง“๊ธฐ ์œ„ํ•ด ์ง€์–ด์ ธ์•ผํ•  ๊ฑด๋ฌผ(type1), ์ง“๊ณ  ๋‚˜์„œ ์ง€์„ ์ˆ˜ ์žˆ๋Š” ๊ฑด๋ฌผ(type2)์„ ๋”ฐ๋กœ ์ €์žฅ
    • type2๋ฅผ ์ด์šฉํ•ด์„œ ์œ„์ƒ์ •๋ ฌ ์ˆœ์„œ๋ฅผ ๊ตฌํ•˜๊ณ 
    • type1์„ ์ด์šฉํ•ด์„œ ์œ„์ƒ์ •๋ ฌ ์ˆœ์„œ๋Œ€๋กœ ์ด์ „์— ์ง€์–ด์ ธ์•ผํ•  ๊ฑด๋ฌผ์—๋‹ค๊ฐ€ ํ˜„์žฌ ๊ฑด๋ฌผ์˜ ์‹œ๊ฐ„์„ ๋”ํ•ด์ฃผ์ž.
    • ๊ทธ๋Ÿฌ๋ฉด ์ฃผ์–ด์ง„ ๊ทธ๋ž˜ํ”„ ๋…ธ๋“œ์˜ ์ตœ์†Œ ์‹œ๊ฐ„์ด ์œ„์ƒ์ •๋ ฌ ์ˆœ์œผ๋กœ ๋ชจ๋‘ ๊ตฌํ•ด์ง„๋‹ค.
  • ์ฐจ์ด์ 

๊ฐ ๋…ธ๋“œ๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ ์ตœ์†Œ์‹œ๊ฐ„์„ time(๋…ธ๋“œ)๋กœ ํ‘œํ˜„ํ•˜๊ธฐ๋กœ ํ•˜์ž.

time(B) = a+b ์ด๋‹ค.

time(C) = max(a+b+c, a+c) ์ด๋ฏ€๋กœ a+b+c์ด๋‹ค.

time(D) = max(a+b+d, a+b+c+d) ์ด๋ฏ€๋กœ a+b+c+d์ด๋‹ค.

 

๋”ฐ๋ผ์„œ, ๋ชจ๋“  ๊ฒฝ๋กœ๋ฅผ ํƒ์ƒ‰ํ•ด๋ณผ ํ•„์š”์—†์ด

์ด๋Ÿฌํ•œ ๊ฒฝ๋กœ๋งŒ์ด ๋‹ต์ด ๋  ์ˆ˜ ์žˆ๋‹ค.

 

์ด๋Ÿฐ ๊ด€์ ์—์„œ ๋ฐฐ์—ด์„ ์ด์šฉํ•œ ๊ธฐ์กด์˜ ์ฝ”๋“œ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด, time(D)๋ฅผ ์ฐพ๊ธฐ์œ„ํ•ด A, B, C๋ฅผ ๋ชจ๋‘ ํƒ์ƒ‰ํ•ด๋ด์•ผํ•˜๊ณ  ์ด๋Š” ๋น„ํšจ์œจ์ ์ด๋‹ค.

๋”ฐ๋ผ์„œ, ์œ„์ƒ์ •๋ ฌ์œผ๋กœ A => B => C => D๋ผ๋Š” ๊ฒฝ๋กœ๋ฅผ ์ฐพ์•„๋‘” ํ›„ time(D)๋ฅผ ๊ตฌํ•˜๋ฉด ๋” ํšจ์œจ์ ์œผ๋กœ ๊ตฌํ•  ์ˆ˜ ์žˆ๋‹ค.

 

๊ฒฐ๊ณผ

์œ„๊ฐ€ ๋ฐฐ์—ด + DP, ์•„๋ž˜๊ฐ€ ์œ„์ƒ์ •๋ ฌ์ด๋‹ค.

์—ญ์‹œ ๋ฐฐ์—ด์„ ์ด์šฉํ•˜๋ฉด ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ๋งŽ์ด ๋“ค์ง€๋งŒ ์ ‘๊ทผ ์‹œ๊ฐ„์ด ์ƒ์ˆ˜ ๋ณต์žก๋„์ด๋ฏ€๋กœ ์‹œ๊ฐ„์ด ๋น ๋ฅด๋‹ค. ์œ„์ƒ์ •๋ ฌ์„ ์ด์šฉํ•œ ๋ฐฉ๋ฒ•์€ ์ด์–ด์ง€๋Š” ๋…ธ๋“œ๋“ค๋งŒ ์ €์žฅํ•˜๋ฉด ๋˜๋ฏ€๋กœ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์ ๊ฒŒ ๋“ ๋‹ค.

 

์ด๋ก ์ƒ์œผ๋กœ๋Š” ์œ„์ƒ์ •๋ ฌ์ด ์‹œ๊ฐ„์ด ๋” ์ ๊ฒŒ ๊ฑธ๋ ค์•ผํ•˜์ง€๋งŒ ์œ„์ƒ์ •๋ ฌ์„ ๊ตฌํ˜„ํ•˜๊ธฐ ์œ„ํ•ด ์“ด vector๋ผ๋Š” ์ž๋ฃŒ๊ตฌ์กฐ์˜ ์—ฐ์‚ฐ ๋•Œ๋ฌธ์— ์‹œ๊ฐ„์ด ๋” ๋งŽ์ด ๊ฑธ๋ฆฌ๋Š” ๊ฒƒ ๊ฐ™๋‹ค.

๋ฐ˜์‘ํ˜•