๋ณธ๋ฌธ์œผ๋กœ ๋ฐ”๋กœ๊ฐ€๊ธฐ
728x90
๐Ÿ”—๋ฌธ์ œ ๋ณด๋Ÿฌ๊ฐ€๊ธฐ
 

2637๋ฒˆ: ์žฅ๋‚œ๊ฐ ์กฐ๋ฆฝ

์ฒซ์งธ ์ค„์—๋Š” ์ž์—ฐ์ˆ˜ N(3 ≤ N ≤ 100)์ด ์ฃผ์–ด์ง€๋Š”๋ฐ, 1๋ถ€ํ„ฐ N-1๊นŒ์ง€๋Š” ๊ธฐ๋ณธ ๋ถ€ํ’ˆ์ด๋‚˜ ์ค‘๊ฐ„ ๋ถ€ํ’ˆ์˜ ๋ฒˆํ˜ธ๋ฅผ ๋‚˜ํƒ€๋‚ด๊ณ , N์€ ์™„์ œํ’ˆ์˜ ๋ฒˆํ˜ธ๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ทธ ๋‹ค์Œ ์ค„์—๋Š” ์ž์—ฐ์ˆ˜ M(3 ≤ M ≤ 100)์ด ์ฃผ

www.acmicpc.net

 

๐Ÿ‘จ‍๐Ÿ’ปํ’€์ด ๊ณผ์ •

 

์œ„์ƒ ์ •๋ ฌ๊ณผ ๋‹ค์ด๋‚˜๋ฏน ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ํ†ตํ•ด ํ’€์—ˆ์Šต๋‹ˆ๋‹ค. ์ฒ˜์Œ์—๋Š” DFS๋กœ ํ’€ ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™๋‹จ ์ƒ๊ฐ์— ๋„์ „ํ•˜๋ ค๊ณ  ํ–ˆ๋Š”๋ฐ, ์ค‘๋ณต๋˜๋Š” ๊ณ„์‚ฐ์ด ๋„ˆ๋ฌด ๋งŽ์•„ ์‹œ๊ฐ„ ์ดˆ๊ณผ๊ฐ€ ๋‚  ๊ฒƒ ๊ฐ™๋‹จ ์ƒ๊ฐ์ด ๋“ค์–ด ๊ทธ ํ’€์ด๋Š” ํฌ๊ธฐํ–ˆ์Šต๋‹ˆ๋‹ค. ์•„๋ฌดํŠผ, ์ œ๊ฐ€ ์–ด๋–ป๊ฒŒ ํ’€์—ˆ๋Š”์ง€ ์ฒœ์ฒœํžˆ ์„ค๋ช…ํ•ด ๋“œ๋ฆฌ๋„๋ก ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค.

 

 

1. ๊ฐ„์„  ์ •๋ณด ๋ฐ ์ง„์ž… ์ฐจ์ˆ˜ ์„ค์ •

 

ํ•˜์œ„ ๋ถ€ํ’ˆ์—์„œ ์ƒ์œ„ ๋ถ€ํ’ˆ์œผ๋กœ ๊ฐ„์„ ์ด ๊ฐ€๋ฆฌํ‚ค๋„๋ก ๋ฐฉํ–ฅ์„ ์„ค์ •ํ•˜์˜€๊ณ , ํ•„์š”ํ•œ ๋ถ€ํ’ˆ ๊ฐœ์ˆ˜ ์ •๋ณด๋„ ๊ฐ™์ด ๊ด€๋ฆฌํ•˜์˜€์Šต๋‹ˆ๋‹ค.

#include <vector>
using namespace std;
using Part = pair<int, int>;	// <๋ถ€ํ’ˆ ๋ฒˆํ˜ธ, ํ•„์š”ํ•œ ๊ฐœ์ˆ˜>


int main() {
    int N, M;
    cin >> N >> M;
    
    // ๊ฐ„์„  ์ •๋ณด ๋ฐ ์ง„์ž… ์ฐจ์ˆ˜ ์ •๋ณด ๋“ฑ๋ก
    vector<vector<Part>> parts(N + 1, vector<Part>());
    vector<int> inDegrees(N + 1);
    int upperPart, lowerPart, count;

    for (int i = 0; i < M; i++) {
        cin >> upperPart >> lowerPart >> count;
        
        parts[lowerPart].emplace_back(upperPart, count);
        inDegrees[upperPart]++;
    }
    
    //...
}

 

๋ฌธ์ œ์— ๋‚˜์™€์žˆ๋˜ ์˜ˆ์ œ๋ฅผ ํ†ตํ•ด ๊ทธ๋ž˜ํ”„๋ฅผ ๊ตฌ์„ฑํ•˜๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

 

๊ทธ๋ž˜ํ”„

 

 

2) 2์ฐจ์› DP ๋ฐฐ์—ด์„ ํ†ตํ•œ ๊ธฐ๋ณธ ๋ถ€ํ’ˆ ๊ฐœ์ˆ˜ ๊ธฐ์–ต

 

2์ฐจ์› ๋ฐฐ์—ด DP๋ฅผ ์„ ์–ธํ•ฉ๋‹ˆ๋‹ค. DP[i][j]์˜ ๋œป์€ i๋ฒˆ ๋ถ€ํ’ˆ์„ 1๊ฐœ ๋งŒ๋“œ๋Š”๋ฐ ํ•„์š”ํ•œ j๋ฒˆ ๋ถ€ํ’ˆ์˜ ์ „์ฒด ๊ฐœ์ˆ˜๋ผ๋Š” ๋œป์ด์ฃ .

์˜ˆ๋ฅผ ๋“ค์–ด, 6๋ฒˆ ๋ถ€ํ’ˆ์„ ๋งŒ๋“œ๋Š” ๋ฐ ํ•„์š”ํ•œ 1๋ฒˆ ๋ถ€ํ’ˆ์˜ ์ด ๊ฐœ์ˆ˜ DP[6][1] = 4 ๊ฐ€ ๋  ๊ฒ๋‹ˆ๋‹ค. ์ด์™€ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ์ €์žฅํ•ด ์ค„ ๊ฒ๋‹ˆ๋‹ค.

 

๊ทธ๋Ÿฌ๊ธฐ ์œ„ํ•ด, 1๋ฒˆ ๋ถ€ํ’ˆ๋ถ€ํ„ฐ N๋ฒˆ ๋ถ€ํ’ˆ๊นŒ์ง€ ์ˆœํšŒํ•˜๋ฉฐ ์ง„์ž… ์ฐจ์ˆ˜๊ฐ€ 0์ธ ๋ถ€ํ’ˆ i๋ฅผ ์ฐพ์Šต๋‹ˆ๋‹ค.

์ง„์ž… ์ฐจ์ˆ˜๊ฐ€ 0์ด๋ผ๋Š” ๊ฒƒ์€ ๊ธฐ๋ณธ ๋ถ€ํ’ˆ์ด๋ผ๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•˜๊ธฐ ๋•Œ๋ฌธ์ด์ฃ .

 

๋ถ€ํ’ˆ i๋ฅผ ์ฐพ์•˜๋‹ค๋ฉด, ์œ„์ƒ ์ •๋ ฌ์„ ์œ„ํ•œ ํ(Queue)์— ์ง‘์–ด ๋„ฃ์Œ๊ณผ ๋™์‹œ์—, DP[i][i] = 1๋กœ ์ดˆ๊ธฐํ™” ํ•ด์ฃผ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

*(๊ธฐ๋ณธ ๋ถ€ํ’ˆ์ธ ์ž๊ธฐ ์ž์‹ ์„ ๋งŒ๋“œ๋Š” ๋ฐ ํ•„์š”ํ•œ ๊ฐœ์ˆ˜๋Š” 1์ด๊ธฐ ๋•Œ๋ฌธ์ด์ฃ .)

vector<vector<int>> dp(N + 1, vector<int>(N + 1));
queue<int> nextParts;

for (int i = 1; i <= N; i++) {
    if (inDegrees[i] == 0) {
        dp[i][i] = 1;
        nextParts.push(i);
    }
}

 

์œ„์—์„œ ๋ดค๋˜ ์˜ˆ์ œ๋ฅผ ํ† ๋Œ€๋กœ ์ด ๊ณผ์ •์„ ์ง„ํ–‰ํ•ด์ค€๋‹ค๋ฉด, ๋‹ค์Œ๊ณผ ๊ฐ™์€ 2์ฐจ์› ๋ฐฐ์—ด์ด ๋  ๊ฒ๋‹ˆ๋‹ค.

 

๊ธฐ๋ณธ ๋ถ€ํ’ˆ์œผ๋กœ ์ดˆ๊ธฐํ™” ๋œ 2์ฐจ์› DP ๋ฐฐ์—ด

 

์ด์ œ ์œ„์ƒ ์ •๋ ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ ์šฉํ•ด ์ค์‹œ๋‹ค.

for (int i = 1; i <= N; i++) {
    int lowerPart = nextParts.front();
    nextParts.pop();

    for (const auto& upperLevel : parts[lowerPart]) {
        int upperPart = upperLevel.first;
        int upperPartCount = upperLevel.second;
        
        // -------์ค‘์š”-------
        for (int i = 1; i <= N; i++)
            dp[upperPart][i] += dp[lowerPart][i] * upperPartCount;
        // -------์ค‘์š”-------

        if (--inDegrees[upperPart] == 0)
            nextParts.push(upperPart);
    }
}

 

DP[i] ํ–‰์—๋Š” i๋ฒˆ ๋ถ€ํ’ˆ 1๊ฐœ๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•œ, ๋ชจ๋“  ๋ถ€ํ’ˆ ์žฌ๋ฃŒ ๊ฐœ์ˆ˜๊ฐ€ ๋“ค์–ด์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ์ œ์—์„œ 5๋ฒˆ ๋ถ€ํ’ˆ์„ ๋งŒ๋“ค๊ธฐ ์œ„ํ•ด์„ , 1๋ฒˆ ๋ถ€ํ’ˆ 2๊ฐœ์™€ 2๋ฒˆ ๋ถ€ํ’ˆ 2๊ฐœ๊ฐ€ ํ•„์š”ํ•˜๋‹ค๊ณ  ๋‚˜์™€ ์žˆ์Šต๋‹ˆ๋‹ค.

 

๊ทธ๋ ‡๋‹ค๋ฉด 1๋ฒˆ ๋ถ€ํ’ˆ์„ ๋งŒ๋“œ๋Š” ๋ฐ ํ•„์š”ํ•œ i ๋ฒˆ์งธ ๋ถ€ํ’ˆ * 2 ํ•œ ๊ฐ’์„ 5๋ฒˆ ๋ถ€ํ’ˆ์„ ๋งŒ๋“œ๋Š” ๋ฐ ํ•„์š”ํ•œ i ๋ฒˆ์งธ ๋ถ€ํ’ˆ ๊ฐœ์ˆ˜์— ๋”ํ•ด์ค˜์•ผ๊ฒ ์ฃ . ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ 2๋ฒˆ ๋ถ€ํ’ˆ์„ ๋งŒ๋“œ๋Š” ๋ฐ ํ•„์š”ํ•œ i ๋ฒˆ์งธ ๋ถ€ํ’ˆ * 2 ํ•œ ๊ฐ’์„ 5๋ฒˆ ๋ถ€ํ’ˆ์„ ๋งŒ๋“œ๋Š” ๋ฐ ํ•„์š”ํ•œ i ๋ฒˆ์งธ ๋ถ€ํ’ˆ ๊ฐœ์ˆ˜์— ๋”ํ•ด์ฃผ๋ฉด ๋  ๊ฒ๋‹ˆ๋‹ค. 

 

์ด๊ฑธ ์ฝ”๋“œ ์ƒ์œผ๋กœ ๋‚˜ํƒ€๋‚ธ ๊ฒŒ ๋‹ค์Œ ์ฝ”๋“œ์ž…๋‹ˆ๋‹ค.

for (int i = 1; i <= N; i++)
    dp[upperPart][i] += dp[lowerPart][i] * upperPartCount;

 

์ด ๋ถ€๋ถ„๋งŒ ์ถ”๊ฐ€ํ•ด์ฃผ๊ณ , ๋‚˜๋จธ์ง€๋Š” ์œ„์ƒ ์ •๋ ฌ์„ ํ•ด์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

์œ„์ƒ ์ •๋ ฌ์ด ๋๋‚ฌ๋‹ค๋ฉด, dp[N]์— ํ•ด๋‹นํ•˜๋Š” ํ–‰์—์„œ 0์„ ์ œ์™ธํ•œ ๊ฐ’๋“ค์„ ์ฐจ๋ก€๋Œ€๋กœ ์ถœ๋ ฅํ•ด์ฃผ๋ฉด ๋ฉ๋‹ˆ๋‹ค.

* dp[N][5] = 0 ์ด๋ผ๋Š” ๊ฒƒ์€ 5๋ฒˆ ๋ถ€ํ’ˆ์ด ๊ธฐ๋ณธ ๋ถ€ํ’ˆ์ด ์•„๋‹ˆ๋ผ๋Š” ๊ฑธ ๋œปํ•˜๊ธฐ ๋•Œ๋ฌธ์ด์ฃ .

 

 

โœ๏ธ์†Œ์Šค ์ฝ”๋“œ ๋ฐ ๊ฒฐ๊ณผ

#include <iostream>
#include <vector>
#include <queue>

using namespace std;
using Part = pair<int, int>;    // <๋ถ€ํ’ˆ ๋ฒˆํ˜ธ, ํ•„์š” ๊ฐœ์ˆ˜>
#define FAST_IO ios::sync_with_stdio(false); cout.tie(NULL); cin.tie(NULL);

vector<int> Solution(const vector<vector<Part>>& parts, vector<int>& inDegrees, int N) {
    vector<vector<int>> dp(N + 1, vector<int>(N + 1));
    queue<int> nextParts;

    for (int i = 1; i <= N; i++) {
        if (inDegrees[i] == 0) {
            dp[i][i] = 1;
            nextParts.push(i);
        }
    }

    for (int i = 1; i <= N; i++) {
        int lowerPart = nextParts.front();
        nextParts.pop();

        for (const auto& upperLevel : parts[lowerPart]) {
            int upperPart = upperLevel.first;
            int upperPartCount = upperLevel.second;

            for (int i = 1; i <= N; i++)
                dp[upperPart][i] += dp[lowerPart][i] * upperPartCount;

            if (--inDegrees[upperPart] == 0)
                nextParts.push(upperPart);
        }
    }

    return dp[N];
 }


int main() {
    FAST_IO
    int N, M;
    cin >> N >> M;

    vector<vector<Part>> parts(N + 1, vector<Part>());
    vector<int> inDegrees(N + 1);
    int upperPart, lowerPart, count;

    for (int i = 0; i < M; i++) {
        cin >> upperPart >> lowerPart >> count;
        parts[lowerPart].emplace_back(upperPart, count);
        inDegrees[upperPart]++;
    }

    vector<int> answers = Solution(parts, inDegrees, N);

    for (int i = 1; i <= N; i++) {
        if (answers[i] != 0)
            cout << i << " " << answers[i] << "\n";
    }    

    return 0;
}

 

 

728x90
๋ฐ˜์‘ํ˜•