unagi11
이국의 보조기억장치
unagi11
전체 방문자
오늘
어제
  • 전체 글 (35)
    • Technology (28)
      • Algorithm Theory (10)
      • Problem Solving (14)
      • Unreal (1)
      • Unity (1)
      • Cocos2d (0)
      • etc (2)
    • Develop (5)
      • Dungeon-Chess (0)
      • Past Projects (3)
      • etc (2)
    • Daily (2)

블로그 메뉴

  • 깃허브
  • 프로필

인기 글

최근 글

hELLO · Designed By 정상우.
unagi11

이국의 보조기억장치

Technology/Problem Solving

[BOJ] 6086번: 최대 유량

2022. 5. 28. 11:33
 

6086번: 최대 유량

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

www.acmicpc.net

제한 조건
- 시간 제한 : 1s
- 공간 제한 : 128MB

풀이 사용 
- 사용 언어 : C++17
- 사용 시간 : 0ms
- 사용 공간 : 1352KB
- 시도 회수 : 6회

풀이 설명
- 최대 유량문제
- Ford-Fulkerson method에서 augmenting path를 DFS순서대로 찾는 Edmonds-Karp Algorithm을 사용하였다.
- capacity[u][v] : u에서 v로 갈수있는 해당 파이프의 최대 용량
- flow[u][v] : u에서 v로 갈수있는 유량. flow를 0으로 두고 Residual Network에서 augmenting path를 찾아서 계속 업데이트 해간다.
- residual capacity[u][v] : u에서 v로 유량을 보내고 남은 값. augmenting path를 구한뒤에 path의 residual capacity 중 가장 작은 값을 flow에 더해준다. (반대방향은 빼준다.) 
#include <cstdio>
#include <vector>
#include <algorithm>
#include <deque>
#include <stdint.h>

using namespace std;

int num_edges;

int capacity[INT8_MAX][INT8_MAX] = {0};
int flow[INT8_MAX][INT8_MAX] = {0};

int main(int argc, char const *argv[])
{
    scanf("%d\n", &num_edges);

    for (int i = 0; i < num_edges; i++)
    {
        char from, to;
        int cost;
        scanf("%c %c %d\n", &from, &to, &cost);

        if (from == to)
            continue;

        capacity[from][to] += cost;
        capacity[to][from] += cost;
    }

    int answer = 0;
    bool isNoAugmentPath = false;

    while (!isNoAugmentPath)
    {
        deque<char> queue = {'A'};
        int parent[INT8_MAX] = {0};
        bool isVisited[INT8_MAX] = {false};
        isVisited['A'] = true;
        isNoAugmentPath = true;

        // DFS로 augmenting path 찾기
        while (!queue.empty())
        {
            char u = queue.front();
            queue.pop_front();

            // 목적지 Z가 아니라면
            if (u != 'Z')
            {
                for (int v = 0; v < INT8_MAX; v++)
                {
                    if (capacity[u][v] - flow[u][v] > 0 && isVisited[v] == false)
                    {
                        queue.push_back(v);
                        parent[v] = u;
                        isVisited[v] = true;
                    }
                }
            }
            // 목적지 Z에 도달했다면
            else
            {
                isNoAugmentPath = false;

                // min augment를 찾는다.
                int min_augment = INT32_MAX;
                char index = 'Z';
                while (index != 'A')
                {
                    int pred = parent[index];
                    min_augment = min(min_augment, capacity[pred][index] - flow[pred][index]);
                    index = pred;
                }
                answer += min_augment;

                index = 'Z';
                while (index != 'A')
                {
                    int pred = parent[index];
                    flow[pred][index] = flow[pred][index] + min_augment;
                    flow[index][pred] = flow[index][pred] - min_augment;
                    index = pred;
                }
                break;
            }
        }
    }

    printf("%d", answer);

    return 0;
}

 

 
 
 
저작자표시 변경금지 (새창열림)
    'Technology/Problem Solving' 카테고리의 다른 글
    • [BOJ] 18138번: 리유나는 세일러복을 좋아해
    • [BOJ] 1162번: 도로포장
    • [BOJ] 1738번: 골목길
    • [BOJ] 2152번: 여행 계획 세우기
    unagi11
    unagi11
    개발하고 기록하자

    티스토리툴바