기술 블로그

17412번 도시 왕복하기 1 본문

알고리즘 문제/BOJ

17412번 도시 왕복하기 1

parkit 2019. 9. 29. 13:35
728x90
반응형

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


mcmf 문제이다.


출발점 : 1

도착점 : 2


c : 용량

w : 비용

f : 유량



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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#include <bits/stdc++.h>
 
using namespace std;
 
#define Max 500
#define INF 987654321
 
int w[Max][Max], c[Max][Max], f[Max][Max], d[Max], dist[Max], N, P;
bool inQ[Max];
vector<int> v[Max];
 
int mcmf()
{
    int ret = 0, min_cost = 0;
 
    while (true)
    {
        queue<int> q;
 
        fill(d, d + Max, -1);
        fill(dist, dist + Max, INF);
 
        inQ[1= true;
        dist[1= 0;
        q.push(1);
 
        while (!q.empty())
        {
            int qs = q.size();
 
            while (qs--)
            {
                int here = q.front();
 
                q.pop();
 
                inQ[here] = false;
 
                for (auto next : v[here])
                    if (c[here][next] - f[here][next] > 0 && dist[next] > dist[here] + w[here][next])
                    {
                        // 남는 용량(자체 용량 크기 - 흐르는 유량)이 0 초과로 무조건 있어야 흐를 수 있다.
                        dist[next] = dist[here] + w[here][next];
                        d[next] = here;
 
                        // queue에 들어 있지 않다면
                        if (!inQ[next])
                        {
                            inQ[next] = true;
                            q.push(next);
 
                            if (next == 2break;
                        }
                    }
            }        
        }
 
        // 더 이상 목적지(2)로 갈 수 없다면
        if (d[2== -1break;
 
        int Flow = INF;
 
        for (int i = 2; i != 1; i = d[i])
            Flow = min(Flow, c[d[i]][i] - f[d[i]][i]);
        
        for (int i = 2; i != 1; i = d[i])
        {
            // 총 비용(최소 비용)은 각 간선의 비용(w)에 위에서 구한 최소로 흐르는 유량을 곱한다.
            min_cost += Flow * w[d[i]][i];
            f[d[i]][i] += Flow;
            f[i][d[i]] -= Flow;
        }
        
        ++ret;
    }
 
    return ret;
}
 
int main(void)
{
    //cin.tie(0);
    int from, to;
    scanf("%d %d"&N, &P);
 
    for (int i = 0; i < P; i++)
    {
        scanf("%d %d"&from, &to);
 
        v[from].push_back(to);
        v[to].push_back(from);
 
        w[from][to] = 1;
        w[to][from] = -1;
 
        c[from][to] = 1;
    }
 
    printf("%d\n", mcmf());
 
    return 0;
}
cs































728x90
반응형

'알고리즘 문제 > BOJ' 카테고리의 다른 글

2529번 부등호  (0) 2019.10.01
17505번 링고와 순열  (0) 2019.09.30
1092번 배  (0) 2019.09.28
2887번 행성 터널  (0) 2019.09.28
17472번 다리 만들기 2  (0) 2019.09.27