algorithm

BOJ 2056

rkawk 2022. 10. 10. 22:54

문제

더보기

μž‘μ—… μ„±κ³΅

 
2 초 256 MB 11054 5110 3656 43.215%

문제

μˆ˜ν–‰ν•΄μ•Ό ν•  μž‘μ—… N개 (3 ≤ N ≤ 10000)κ°€ μžˆλ‹€. 각각의 μž‘μ—…λ§ˆλ‹€ κ±Έλ¦¬λŠ” μ‹œκ°„(1 ≤ μ‹œκ°„ ≤ 100)이 μ •μˆ˜λ‘œ μ£Όμ–΄μ§„λ‹€.

λͺ‡λͺ‡ μž‘μ—…λ“€ μ‚¬μ΄μ—λŠ” μ„ ν–‰ κ΄€κ³„λΌλŠ” 게 μžˆμ–΄μ„œ, μ–΄λ–€ μž‘μ—…μ„ μˆ˜ν–‰ν•˜κΈ° μœ„ν•΄ λ°˜λ“œμ‹œ λ¨Όμ € μ™„λ£Œλ˜μ–΄μ•Ό ν•  μž‘μ—…λ“€μ΄ μžˆλ‹€. 이 μž‘μ—…λ“€μ€ λ²ˆν˜Έκ°€ μ•„μ£Ό 예쁘게 맀겨져 μžˆμ–΄μ„œ, K번 μž‘μ—…μ— λŒ€ν•΄ μ„ ν–‰ 관계에 μžˆλŠ”(즉, K번 μž‘μ—…μ„ μ‹œμž‘ν•˜κΈ° 전에 λ°˜λ“œμ‹œ λ¨Όμ € μ™„λ£Œλ˜μ–΄μ•Ό ν•˜λŠ”) μž‘μ—…λ“€μ˜ λ²ˆν˜ΈλŠ” λͺ¨λ‘ 1 이상 (K-1) μ΄ν•˜μ΄λ‹€. μž‘μ—…λ“€ μ€‘μ—λŠ”, 그것에 λŒ€ν•΄ μ„ ν–‰ 관계에 μžˆλŠ” μž‘μ—…μ΄ ν•˜λ‚˜λ„ μ—†λŠ” μž‘μ—…μ΄ λ°˜λ“œμ‹œ ν•˜λ‚˜ 이상 μ‘΄μž¬ν•œλ‹€. (1번 μž‘μ—…μ΄ 항상 κ·ΈλŸ¬ν•˜λ‹€)

λͺ¨λ“  μž‘μ—…μ„ μ™„λ£Œν•˜κΈ° μœ„ν•΄ ν•„μš”ν•œ μ΅œμ†Œ μ‹œκ°„μ„ κ΅¬ν•˜μ—¬λΌ. λ¬Όλ‘ , μ„œλ‘œ μ„ ν–‰ 관계가 μ—†λŠ” μž‘μ—…λ“€μ€ λ™μ‹œμ— μˆ˜ν–‰ κ°€λŠ₯ν•˜λ‹€.

μž…λ ₯

첫째 쀄에 N이 μ£Όμ–΄μ§„λ‹€.

두 번째 쀄뢀터 N+1번째 μ€„κΉŒμ§€ N개의 쀄이 μ£Όμ–΄μ§„λ‹€. 2번째 쀄은 1번 μž‘μ—…, 3번째 쀄은 2번 μž‘μ—…, ..., N+1번째 쀄은 N번 μž‘μ—…μ„ 각각 λ‚˜νƒ€λ‚Έλ‹€. 각 μ€„μ˜ μ²˜μŒμ—λŠ”, ν•΄λ‹Ή μž‘μ—…μ— κ±Έλ¦¬λŠ” μ‹œκ°„μ΄ λ¨Όμ € μ£Όμ–΄μ§€κ³ , κ·Έ λ‹€μŒμ— κ·Έ μž‘μ—…μ— λŒ€ν•΄ μ„ ν–‰ 관계에 μžˆλŠ” μž‘μ—…λ“€μ˜ 개수(0 ≤ κ°œμˆ˜ ≤ 100)κ°€ μ£Όμ–΄μ§„λ‹€. 그리고 μ„ ν–‰ 관계에 μžˆλŠ” μž‘μ—…λ“€μ˜ λ²ˆν˜Έκ°€ μ£Όμ–΄μ§„λ‹€.

좜λ ₯

첫째 쀄에 λͺ¨λ“  μž‘μ—…μ„ μ™„λ£Œν•˜κΈ° μœ„ν•œ μ΅œμ†Œ μ‹œκ°„μ„ 좜λ ₯ν•œλ‹€.

예제 μž…λ ₯ 1 λ³΅μ‚¬

7
5 0
1 1 1
3 1 2
6 1 1
1 2 2 4
8 2 2 4
4 3 3 5 6

예제 좜λ ₯ 1 λ³΅μ‚¬

23​

 

풀이

μ •ν•΄μ§„ μˆœμ„œμ— 따라 μž‘μ—…μ„ μ‹œν–‰ν•΄ κ·Έλž˜ν”„μƒ λ§ˆμ§€λ§‰ λ…Έλ“œμ— ν•΄λ‹Ήν•˜λŠ” μž‘μ—…μ„ 끝내야 ν•˜λŠ” μœ„μƒμ •λ ¬ λ¬Έμ œμ΄λ‹€.

사이클이 생기면 μœ„μƒμ •λ ¬μ΄ 성립될 수 μ—†μ§€λ§Œ, 이 λ¬Έμ œλŠ” 사이클이 μ•ˆμƒκΈ΄λ‹€λŠ” κ°€μ • ν•˜μ— ν’€λ©΄ λœλ‹€.(지문에 κ΄€λ ¨λ‚΄μš©μ΄ μ—†κΈ° λ•Œλ¬Έ)

 

μš°μ„  μ‹œκ°„, μž‘μ—… μˆ˜ν–‰ μ „ μ™„λ£Œλ˜μ•Όν•  μž‘μ—…μ˜ 수, μž‘μ—… μˆ˜ν–‰ μ „ μ™„λ£Œλ˜μ•Όν•  μž‘μ—… λ²ˆν˜Έκ°€ μ£Όμ–΄μ§„λ‹€.

κ·ΈλŸ¬λ―€λ‘œ 이λ₯Ό ꡬ쑰체λ₯Ό 톡해 μ„ μ–Έν•΄μ£Όμ—ˆλ‹€.

struct p{
    int time;
    vector<int>edges;
    int num;
};

그런데 μ—¬κΈ°μ„œ edges 벑터에 λ“€μ–΄κ°€μ•Ό ν•˜λŠ” 값듀은 μˆ˜ν–‰ μ „ μ™„λ£Œλ˜μ•Όν•  μž‘μ—… λ²ˆν˜Έκ°€ μ•„λ‹ˆλΌ 이 μž‘μ—… μˆ˜ν–‰ ν›„ μˆ˜ν–‰λ  μž‘μ—…μ— λ²ˆν˜Έκ°€ λ“€μ–΄κ°€μ•Ό ν•œλ‹€.

 

μœ„μƒμ •λ ¬μ—μ„œλŠ” 일의 μˆœμ„œμ— 따라 κ°„μ„ μ˜ λ°©ν–₯이 μž‘ν˜€μ•Ό ν•˜λ―€λ‘œ κ·Έλ ‡λ‹€. 

 

λ˜ν•œ, νŠΉμ • μž‘μ—…μ— λŒ€ν•œ ꡬ쑰체λ₯Ό 인덱슀λ₯Ό 톡해 λ°”λ‘œ μ ‘κ·Όν•  수 있게 ν•˜κΈ° μœ„ν•΄ ꡬ쑰체 pν˜• 벑터λ₯Ό ν•˜λ‚˜ μ„ μ–Έν•΄μ£Όμ—ˆλ‹€.

vector<p>v(10001);

μž…λ ₯λ°›μ„λ•Œ 간선정보 μž…λ ₯λ°›λŠ” 뢀뢄에 μ£Όμ˜ν•˜μž. μž…λ ₯받은 μž‘μ—…μ— ν˜„μž¬ μž‘μ—…μ„ λ„£μ–΄μ£Όμ–΄μ•Ό ν•œλ‹€.

for(int i=1; i<=N; i++){
        int time, s_num;
        cin>>time>>s_num;
        if(s_num == 0) q.push(i);
        v[i].time = time;
        v[i].num = s_num;
        for(int j=0; j<s_num; j++){
            int s;
            cin>>s;
            v[s].edges.push_back(i);
        }
    }

κ·Έ λ‹€μŒμ€ μœ„μƒμ •λ ¬μ„ ν•˜λŠ” μ½”λ“œμΈλ°, 이 λ¬Έμ œμ—μ„œλŠ” νŠΉμ • μž‘μ—…μ΄ μ‹œν–‰λ˜κΈ° 이전에 μ‹œκ°„μ΄ μ–Όλ§ˆλ‚˜ κ±Έλ Έλ‚˜λ₯Ό λ”°λ‘œ 기둝해야 ν•œλ‹€.

queueμ—μ„œ 맨 μ•žμœΌλ‘œ κ°€λŠ” κ²½μš°κ°€ νŠΉμ • μž‘μ—…μ΄ μ‹œν–‰λ˜λŠ” κ²½μš°μ΄λ―€λ‘œ arr[q.front()] 에 κ·Έ μž‘μ—…μ΄ μ–Όλ§ˆλ‚˜ κ±Έλ Έλ‚˜λ₯Ό λ°”λ‘œ 더해주고,

q.front()에 ν•΄λ‹Ήν•˜λŠ” μž‘μ—…μ΄ λλ‚œ ν›„ μ‹œν–‰λ˜λŠ” μž‘μ—…μ˜ 값에 q.front() μž‘μ—…μ΄ λλ‚œ μ‹œκ°„μ„ λΉ„κ΅ν•΄μ„œ λ„£μ–΄μ£Όμ–΄μ•Ό ν•œλ‹€.

κ°„μ„ μ˜ 거리가 같은 μž‘μ—…μ€ λ™μ‹œκ°„μ— μˆ˜ν–‰λ  수 있기 λ•Œλ¬Έμ— λŒ€μ†ŒλΉ„κ΅λ₯Ό 톡해 값을 λ„£μ–΄μ€€λ‹€.

 

μ€‘μš”ν•œκ±΄ v[cur].edgesλ₯Ό 톡해 λ³΄λŠ” μž‘μ—…λ“€μ€ 무쑰건 ν˜„μž¬ μž‘μ—…κ³Ό 거리가 κ°„μ„  ν•˜λ‚˜λ°–μ— μ•ˆλœλ‹€λŠ” 것이닀.

for(int i=1; i<=N; i++){
        int cur = q.front();
        q.pop();
        arr[cur] +=  v[cur].time;
        for(auto e : v[cur].edges){
            v[e].num -= 1;
            if(v[e].num == 0)
                q.push(e);
            if(arr[e] < arr[cur]) arr[e] = arr[cur];
        }
    }

 

전체 μ½”λ“œ

#include <iostream>
#include <queue>
#include <vector>
using namespace std;
int N, arr[10001], ans;
queue<int>q;
struct p{
    int time;
    vector<int>edges;
    int num;
};
vector<p>v(10001);
int main(){
    cin>>N;
    for(int i=1; i<=N; i++){
        int time, s_num;
        cin>>time>>s_num;
        if(s_num == 0) q.push(i);
        v[i].time = time;
        v[i].num = s_num;
        for(int j=0; j<s_num; j++){
            int s;
            cin>>s;
            v[s].edges.push_back(i);
        }
    }
    for(int i=1; i<=N; i++){
        int cur = q.front();
        q.pop();
        arr[cur] +=  v[cur].time;
        for(auto e : v[cur].edges){
            v[e].num -= 1;
            if(v[e].num == 0)
                q.push(e);
            if(arr[e] < arr[cur]) arr[e] = arr[cur];
        }
    }
    for(int i=1; i<=N; i++)
        ans = max(ans, arr[i]);
    cout<<ans;

}