Doby's Lab

백준 6086번: 최대 유량 (C++) 본문

PS/BOJ

백준 6086번: 최대 유량 (C++)

도비(Doby) 2022. 3. 19. 19:07

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

 

6086번: 최대 유량

첫째 줄에 정수 N (1 ≤ N ≤ 700)이 주어진다. 둘째 줄부터 N+1번째 줄까지 파이프의 정보가 주어진다. 첫 번째, 두 번째 위치에 파이프의 이름(알파벳 대문자 또는 소문자)이 주어지고, 세 번째 위

www.acmicpc.net


Solved By:  Edmonds-Karp

 

처음으로 최대 유량 문제를 풀어보았습니다. BFS를 활용한 Edmonds-Karp를 사용했습니다.

 

#include <iostream>
#include <queue>
#include <vector>
#include <cstring>
#define MAX ('z' - 'A' + 1)
#define INF 1e9
using namespace std;

int c[MAX][MAX];
int f[MAX][MAX];
vector<int> adj[MAX];
int parent[MAX];
int resultMaxFlow = 0;

int n;

// BFS를 활용하여 Edmonds-Karp
int maximumFlow(int source, int sink){
    while(true){
        memset(parent, -1, sizeof(parent));
        queue<int> q; //BFS Queue
        
        q.push(source);
        // BFS, 잔여 용량이 남아있는 것을 확인하며
        // sink로 갈 수 있는지 확인
        while(!q.empty()){
            int now = q.front();
            q.pop();
            
            for(int i = 0; i < adj[now].size(); i++){
                int next = adj[now][i];
                
                if((c[now][next] - f[now][next] > 0)
                && (parent[next] == -1)){
                    q.push(next);
                    parent[next] = now;
                    if(next == sink) break;
                }
            }
            // 이 BFS의 역할은 잔여용량 확인 후, sink를 갈 수 있느냐가
            // 관건임. sink만 탐색 되면 된다.
            if(parent[sink] != -1) break;
        }
        
        // BFS 탐색이 끝났는데 sink로 가는 경로가 없다는 것은
        // source에서 sink로 더 이상 갈 수 없다는 의미
        // >>종료
        if(parent[sink] == -1) break;
        
        int tempMaxFlow = INF;
        int residualCapacity; // 잔여 용량
        
        for(int i = sink; i != source; i = parent[i]){
            // source에서 sink로 온 경로를 보면서 (잔여 용량 확인)
            // 흘려보낼 수 있는 최대 유량을 최솟값 갱신을 통해 확인
            residualCapacity = c[parent[i]][i] - f[parent[i]][i];
            tempMaxFlow = min(tempMaxFlow, residualCapacity);
        }
        
        for(int i = sink; i != source; i = parent[i]){
            f[parent[i]][i] += tempMaxFlow;
            // 유량의 대칭성으로 인한 역간선 갱신
            f[i][parent[i]] -= tempMaxFlow;
        }
        
        resultMaxFlow += tempMaxFlow;
    }
    
    return resultMaxFlow;
}

int main(){
    cin >> n;
    for(int i = 0; i < n; i++){
        char a, b; int capacity;
        cin >> a >> b >> capacity;
        
        adj[a - 'A'].push_back(b - 'A');
        adj[b - 'A'].push_back(a - 'A');
        
        c[a - 'A'][b - 'A'] += capacity;
        c[b - 'A'][a - 'A'] += capacity;
    }
    
    cout << maximumFlow('A' - 'A', 'Z' - 'A');
    return 0;
}
728x90