백준 #17412 도시 왕복하기 1


BOJ #17412 - 도시 왕복하기 1

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

# 문제 분류

최대 유량

풀이 접근 방법


최대 유량을 사용하면 되는 문제이다.


#include <algorithm>
#include <cmath>
#include <cstring>
#include <iostream>
#include <queue>
#include <utility>
#include <vector>

#define mp make_pair
#define pb push_back
#define X first
#define Y second
#define fup(i, a, b, c) for (int(i) = (a); (i) <= (b); (i) += (c))
#define fdn(i, a, b, c) for (int(i) = (a); (i) >= (b); (i) -= (c))
#define endl "\n"

using namespace std;

typedef long long ll;
typedef pair<ll, ll> pl;
typedef pair<int, int> pi;
typedef vector<int> vi;
typedef vector<pi> vii;
const ll MOD = 1e9 + 7;
const int stMAX = 1 << 18;
const int INF = 1e9;
const int MAX_V = 410;

int c[MAX_V][MAX_V], f[MAX_V][MAX_V];
int level[MAX_V], work[MAX_V];
vi adj[MAX_V];
int S = 1, E = 2;

// 여기 수정
bool bfs() {
    fill(level, level + MAX_V, -1);
    level[S] = 0;

    queue<int> Q;
    Q.push(S);
    while (!Q.empty()) {
        int curr = Q.front();
        Q.pop();
        for (int next : adj[curr]) {

            if (level[next] == -1 && c[curr][next] - f[curr][next] > 0) {
                level[next] = level[curr] + 1;
                Q.push(next);
            }
        }
    }

    return level[E] != -1;
}

int dfs(int curr, int dest, int flow) {
    if (curr == dest)
        return flow;

    for (int &i = work[curr]; i < adj[curr].size(); i++) {
        int next = adj[curr][i];
        if (level[next] == level[curr] + 1 && c[curr][next] - f[curr][next] > 0) {
            int df = dfs(next, dest, min(c[curr][next] - f[curr][next], flow));
            if (df > 0) {
                f[curr][next] += df;
                f[next][curr] -= df;
                return df;
            }
        }
    }
    return 0;
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);

    int N, P;

    cin >> N >> P;

    fup(_, 1, P, 1) {
        int u, v;
        cin >> u >> v;
        adj[u].pb(v);
        c[u][v] = 1;
        adj[v].pb(u);
        c[v][u] = 0;
    }

    int total = 0;

    while (bfs()) {
        fill(work, work + MAX_V, 0);
        while (1) {
            int flow = dfs(S, E, INF);
            if (flow == 0)
                break;
            total += flow;
        }
    }

    cout << total;
}