2
2
using namespace std ;
3
3
#define ll long long
4
4
5
- struct Aresta {
5
+ struct Edge {
6
6
int u, v; ll cap;
7
- Aresta (int u, int v, ll cap) : u(u), v(v), cap(cap) {}
7
+ Edge (int u, int v, ll cap) : u(u), v(v), cap(cap) {}
8
8
};
9
9
10
10
struct Dinic {
11
11
12
- int n, source , sink;
12
+ int n, src , sink;
13
13
vector<vector<int >> adj;
14
- vector<Aresta> arestas ;
15
- vector<int > level , ptr; // pointer para a próxima aresta não saturada de cada vértice
14
+ vector<Edge> edges ;
15
+ vector<int > lvl , ptr; // pointer para a próxima Edge não saturada de cada vértice
16
16
17
- Dinic (int n, int source , int sink) : n(n), source(source ), sink(sink) { adj.resize (n); }
17
+ Dinic (int n, int src , int sink) : n(n), src(src ), sink(sink) { adj.resize (n); }
18
18
19
- void addAresta (int u, int v, ll cap)
19
+ void addEdge (int u, int v, ll cap)
20
20
{
21
- adj[u].push_back (arestas .size ());
22
- arestas .emplace_back (u, v, cap);
21
+ adj[u].push_back (edges .size ());
22
+ edges .emplace_back (u, v, cap);
23
23
24
- adj[v].push_back (arestas .size ());
25
- arestas .emplace_back (v, u, 0 );
24
+ adj[v].push_back (edges .size ());
25
+ edges .emplace_back (v, u, 0 );
26
26
}
27
27
28
28
ll dfs (int u, ll flow = 1e9 ){
@@ -31,15 +31,15 @@ struct Dinic {
31
31
32
32
for (int &i = ptr[u]; i < adj[u].size (); i++)
33
33
{
34
- int atual = adj[u][i];
35
- int v = arestas[atual ].v ;
34
+ int at = adj[u][i];
35
+ int v = edges[at ].v ;
36
36
37
- if (level [u] + 1 != level [v]) continue ;
37
+ if (lvl [u] + 1 != lvl [v]) continue ;
38
38
39
- if (ll got = dfs (v, min (flow, arestas[atual ].cap )) )
39
+ if (ll got = dfs (v, min (flow, edges[at ].cap )) )
40
40
{
41
- arestas[atual ].cap -= got;
42
- arestas[atual ^1 ].cap += got;
41
+ edges[at ].cap -= got;
42
+ edges[at ^1 ].cap += got;
43
43
return got;
44
44
}
45
45
}
@@ -48,39 +48,39 @@ struct Dinic {
48
48
}
49
49
50
50
bool bfs (){
51
- level = vector<int > (n, n);
52
- level[source ] = 0 ;
51
+ lvl = vector<int > (n, n);
52
+ lvl[src ] = 0 ;
53
53
54
- queue<int > fila ;
55
- fila .push (source );
54
+ queue<int > q ;
55
+ q .push (src );
56
56
57
- while (!fila .empty ())
57
+ while (!q .empty ())
58
58
{
59
- int u = fila .front ();
60
- fila .pop ();
59
+ int u = q .front ();
60
+ q .pop ();
61
61
62
62
for (auto i : adj[u]){
63
- int v = arestas [i].v ;
63
+ int v = edges [i].v ;
64
64
65
- if (arestas [i].cap == 0 || level [v] <= level [u] + 1 ) continue ;
65
+ if (edges [i].cap == 0 || lvl [v] <= lvl [u] + 1 ) continue ;
66
66
67
- level [v] = level [u] + 1 ;
68
- fila .push (v);
67
+ lvl [v] = lvl [u] + 1 ;
68
+ q .push (v);
69
69
}
70
70
}
71
71
72
- return level [sink] < n;
72
+ return lvl [sink] < n;
73
73
}
74
74
75
- bool inCut (int u){ return level [u] < n; }
75
+ bool inCut (int u){ return lvl [u] < n; }
76
76
77
77
ll maxFlow (){
78
78
ll ans = 0 ;
79
79
80
80
while ( bfs () ){
81
81
ptr = vector<int > (n+1 , 0 );
82
82
83
- while (ll got = dfs (source )) ans += got;
83
+ while (ll got = dfs (src )) ans += got;
84
84
}
85
85
86
86
return ans;
@@ -94,27 +94,27 @@ IMPORTANTE! O algoritmo está 0-indexado
94
94
95
95
**Complexity:**
96
96
O( V^2 * E ) -> caso geral
97
- O( sqrt(V) * E ) -> grafos com cap = 1 para toda aresta // matching bipartido
97
+ O( sqrt(V) * E ) -> grafos com cap = 1 para toda Edge // matching bipartido
98
98
99
99
* Informações:
100
- Crie o Dinic: Dinic dinic(n, source , sink);
101
- Adicione as Arestas : dinic.addAresta (u, v, capacity);
100
+ Crie o Dinic: Dinic dinic(n, src , sink);
101
+ Adicione as edges : dinic.addEdge (u, v, capacity);
102
102
Para calcular o Fluxo Máximo: dinic.maxFlow()
103
103
Para saber se um vértice U está no Corte Mínimo: dinic.inCut(u)
104
104
105
105
* Sobre o Código:
106
- vector<Aresta> arestas ; -> Guarda todas as arestas do grafo e do grafo residual
107
- vector<vector<int>> adj; -> Guarda em adj[u] os índices de todas as arestas saindo de u
108
- vector<int> ptr; -> Pointer para a próxima aresta ainda não visitada de cada vértice
109
- vector<int> level ; -> Distância em vértices a partir do Source. Se igual a N o vértice não foi visitado.
106
+ vector<Edge> edges ; -> Guarda todas as edges do grafo e do grafo residual
107
+ vector<vector<int>> adj; -> Guarda em adj[u] os índices de todas as edges saindo de u
108
+ vector<int> ptr; -> Pointer para a próxima Edge ainda não visitada de cada vértice
109
+ vector<int> lvl ; -> Distância em vértices a partir do Source. Se igual a N o vértice não foi visitado.
110
110
A BFS retorna se Sink é alcançavel de Source. Se não é porque foi atingido o Fluxo Máximo
111
111
A DFS retorna um possível aumento do Fluxo
112
112
*****************************LATEX_DESC_END*/
113
113
/* *************************************LATEX_IGNORED_BEGIN
114
114
* Use Cases of Flow
115
115
116
116
+ Minimum cut: the minimum cut is equal to maximum flow.
117
- i.e. to split the graph in two parts, one on the source side and another on sink side.
117
+ i.e. to split the graph in two parts, one on the src side and another on sink side.
118
118
The capacity of each edge is it weight.
119
119
120
120
+ Edge-disjoint paths: maximum number of edge-disjoint paths equals maximum flow of the
@@ -124,8 +124,8 @@ O( sqrt(V) * E ) -> grafos com cap = 1 para toda aresta // matching bipartido
124
124
path, so limit the flow through a node dividing each node in two. One with incoming edges,
125
125
other with outgoing edges and a new edge from the first to the second with capacity 1.
126
126
127
- + Maximum matching (bipartite): maximum matching is equal to maximum flow. Add a source and
128
- a sink, edges from the source to every node at one partition and from each node of the
127
+ + Maximum matching (bipartite): maximum matching is equal to maximum flow. Add a src and
128
+ a sink, edges from the src to every node at one partition and from each node of the
129
129
other partition to the sink.
130
130
131
131
+ Minimum node cover (bipartite): minimum set of nodes such each edge has at least one
@@ -153,4 +153,4 @@ O( sqrt(V) * E ) -> grafos com cap = 1 para toda aresta // matching bipartido
153
153
maximum sum. a closure is a set of nodes such that there is no edge from a node inside
154
154
the set to a node outside. Is a general case of project selection. Original edges with cap INF.
155
155
Add edges from Source to nodes with W > 0; and from nodes with W < 0 to Sink (cap |W|).
156
- LATEX_IGNORED_END***************************************/
156
+ LATEX_IGNORED_END***************************************/
0 commit comments