Henu
개발냥발
Henu
전체 방문자
오늘
어제
  • 분류 전체보기 (411)
    • DevOps (52)
      • Kubernetes (19)
      • Docker (14)
      • AWS (3)
      • Nginx (4)
      • Linux (4)
      • ArgoCD (1)
      • CN (2)
      • NATS (0)
      • Git (5)
    • Back-End (30)
      • Django (18)
      • Spring (5)
      • JPA (1)
      • MSA (5)
    • CS (87)
      • SystemSoftware (20)
      • OS (25)
      • Computer Architecture (16)
      • Network (23)
      • Database (2)
    • Lang (21)
      • Java (9)
      • Python (4)
      • C# (8)
    • Life (12)
    • 블록체인 (2)
    • Algorithm (204)
      • BOJ (160)
      • 프로그래머스 (19)
      • LeetCode (4)
      • SWEA (1)
      • 알고리즘 문제 해결 전략 (8)
      • DS, algorithms (7)
      • Checkio (5)
    • IT (2)

블로그 메뉴

  • GitHub
  • 글쓰기
  • 관리자

공지사항

  • Free!

인기 글

태그

  • Kubernetes
  • DFS
  • 백트래킹
  • 다이나믹 프로그래밍
  • Network
  • boj
  • django
  • docker
  • BFS
  • 프로그래머스

최근 댓글

최근 글

티스토리

hELLO · Designed By 정상우.
Henu

개발냥발

[백준 11377] 열혈강호 3 (C++)
Algorithm/BOJ

[백준 11377] 열혈강호 3 (C++)

2021. 8. 2. 21:01
 

11377번: 열혈강호 3

첫째 줄에 직원의 수 N과 일의 개수 M, 일을 2개할 수 있는 직원의 수 K가 주어진다. (1 ≤ N, M ≤ 1,000, 1 ≤ K ≤ N) 둘째 줄부터 N개의 줄의 i번째 줄에는 i번 직원이 할 수 있는 일의 개수와 할 수 있

www.acmicpc.net

최대 유량


최대 유량 연습하기

 

열혈 강호 1번 문제와 동일하지만 2가지 일을 할 수 있는 직원의 수가 주어진다.

처음에 무식하게 직원 중에서 k명을 반복해서 뽑고 S에서 해당 직원으로 가는 용량을 2로 두어 매번 에드몬드 카프 알고리즘을 돌려볼까 하는 생각을 했었다. 당연히 그렇게 풀면 안된다.

 

S에서 직원으로 일을 할 수 있는 에너지를 보낸다고 생각했다. 그리고 S말고 다른 정점에서 직원들에게 K만큼의 에너지를 1씩 분배해서 더 줄 수 있다면 풀 수 있다. (K에서 개별 직원에게 주는 에너지의 용량은 1) 

 

K정점을 추가하고 K정점과 S의 용량은 K, K와 직원들 사이의 용량은 1로 두고 에드몬드 카프 알고리즘을 통해 최대 유량을 구하면 된다.

 

에드몬드 카프 알고리즘에서 용량은 반드시 단방향이어야 한다.

유량을 상쇄하기 위해서 음수 flow를 흘려 보낼 수 있는데 이때 음수 flow를 처음 보냄에도 불구하고 용량이 0이 아닌 다른 값이라면 남은 용량의 값이 이상해져서 정점들을 올바르게 탐색하지 못하게 되고 최대유량을 제대로 구할 수 없다.

 

처음에 직원과 일 사이의 용량을 양방향으로 설정해서 계속 틀렸다. 많이 아쉬웠다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#include <cstring>
#define fasti ios_base::sync_with_stdio(false); cin.tie(0);
#define fastio ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);
#define INF 1e9+7
#define pii pair<int, int>
#define MAX 2005
typedef long long ll;
// typedef pair<int, int> pii;
 
using namespace std;
 
int N, M, K;
int capacity[MAX][MAX], flow[MAX][MAX];
vector<int> adj[MAX];
 
void input(){
    cin >> N >> M >> K;
    int a, b;
    adj[0].push_back(2); adj[2].push_back(0);
    capacity[0][2] = K;
    for(int i = 3; i < 3+N; i++){
        cin >> a;
        adj[0].push_back(i); adj[i].push_back(0);
        adj[2].push_back(i); adj[i].push_back(2);
        capacity[0][i] = capacity[2][i] = 1;
        for(int j = 0; j < a; j++){
            cin >> b;
            adj[i].push_back(2+N+b); adj[2+N+b].push_back(i);
            capacity[i][2+N+b] = 1;
        }
    }
    for(int i = 3+N; i < 3+N+M; i++){
        adj[i].push_back(1); adj[1].push_back(i);
        capacity[i][1] = 1;
    }
}
 
void MaxFlow(int source, int sink){
    int total_flow = 0;
    
    while(true){
        vector<int> prev(MAX, -1);
        queue<int> que;
        que.push(source);
        prev[source] = source;
        
        while(!que.empty() && prev[sink] == -1){
            int now = que.front();
            que.pop();
            
            for(int k = 0; k < adj[now].size(); k++){
                int next = adj[now][k];
                if(capacity[now][next] - flow[now][next] > 0 && prev[next] == -1){
                    prev[next] = now;
                    que.push(next);
                }
            }
        }
        if(prev[sink] == -1) break;
        int amount = INF;
        for(int p = sink; p != source; p = prev[p]){
            amount = min(amount, capacity[prev[p]][p] - flow[prev[p]][p]);
        }
        for(int p = sink; p != source; p = prev[p]){
            flow[prev[p]][p] += amount;
            flow[p][prev[p]] -= amount;
        }
        total_flow += amount;
    }
    
    cout << total_flow << "\n";
}
 
int main(){
    fastio
    input();
    MaxFlow(0, 1);
    
    return 0;
}
 
Colored by Color Scripter
cs

 

'Algorithm > BOJ' 카테고리의 다른 글

[백준 2243] 사탕상자 (C++)  (0) 2021.08.03
[백준 13308] 주유소 (C++)  (0) 2021.08.02
[백준 2159] 케익 배달 (C++)  (0) 2021.08.01
[백준 10999] 구간 합 구하기 2 (C++)  (0) 2021.07.31
[백준 1701] Cubeditor (C++)  (0) 2021.07.31
    'Algorithm/BOJ' 카테고리의 다른 글
    • [백준 2243] 사탕상자 (C++)
    • [백준 13308] 주유소 (C++)
    • [백준 2159] 케익 배달 (C++)
    • [백준 10999] 구간 합 구하기 2 (C++)

    티스토리툴바