-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathgraph.hpp
115 lines (95 loc) · 2.04 KB
/
graph.hpp
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
103
104
105
106
107
108
109
110
111
112
113
114
#pragma once
#include <iostream>
#include <queue>
#include <vector>
#include <list>
#include <set>
#include "selectionrule.hpp"
enum Color { FREE = 0, SOURCE, SINK };
class Edge {
private:
public:
int from, to;
int cap;
int flow;
int index;
Edge(int f, int t, int c, int i) :
from(f), to(t), cap(c), flow(0), index(i) {}
};
class Vertex {
private:
public:
std::vector<Edge> e;
Color c;
bool active;
Edge *p;
int height;
int excess;
int si;
int ti;
Vertex(Color c, bool a) :
c(c), active(a), p(NULL), height(0), excess(0), si(0), ti(0) {}
Vertex() :
c(FREE), active(false), p(NULL), height(0), excess(0), si(0), ti(0) {}
};
class FlowGraph {
private:
int N;
int source, sink;
std::vector<Vertex > G;
std::vector<int> count;
SelectionRule& rule;
/* BK stuff */
std::queue<int> bkq;
std::queue<int> orphans;
int lastGrowVertex;
size_t lastIndex;
public:
std::vector<char> cut;
FlowGraph(int N, int source, int sink, SelectionRule& rule) :
N(N),
source(source),
sink(sink),
G(N),
count(N+1),
rule(rule),
lastGrowVertex(-1),
cut(N) {
#ifdef BOYKOV_KOLMOGOROV
bkq.push(source);
bkq.push(sink);
G[source].c = SOURCE;
G[sink].c = SINK;
G[source].active = true;
G[sink].active = true;
#endif
}
int getSource() const { return source; }
int getSink() const { return sink; }
void addEdge(int from, int to, int cap);
void addDoubleEdge(int from, int to, int cap);
void changeCapacity(int from, int index, int cap);
void resetFlow();
void resetHeights();
void push(Edge &e);
void push(Edge &e, int f);
void relabel(int u);
void gap(int h);
void discharge(int u);
void minCutPushRelabel(int source, int sink);
void minCutBK(int source, int sink);
int augment(Edge *e);
int treeCap(const Edge& e, Color col) const;
int treeOrigin(int u, int &len) const;
void adopt();
Edge *grow();
int outFlow(int source);
int inFlow(int sink);
int numActive(void);
bool checkExcess(void);
bool checkTree(void);
bool checkActive(void);
bool checkCapacity(void);
bool checkLabels(void);
bool checkCount(void);
};