-
Notifications
You must be signed in to change notification settings - Fork 8
/
Copy pathrelabelToFront_old.cpp
65 lines (65 loc) · 1.4 KB
/
relabelToFront_old.cpp
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
/* Relabel-to-Front */
// tested with sgu-212 (more testing suggested)
int n,m,layer,src,sink,lvl[MAXN];
int deg[MAXN],adj[MAXN][MAXN];
int res[MAXN][MAXN]; // residual capacity
// graph (i.e. all things above) should be constructed beforehand
list<int> lst; // discharge list
int ef[MAXN],ht[MAXN];
// excess flow, height
int apt[MAXN]; // the next adj index to try push
inline void push(int v,int u) {
int a=min(ef[v],res[v][u]);
ef[v]-=a; ef[u]+=a;
res[v][u]-=a; res[u][v]+=a;
}
inline void relabel(int v) {
int i,u;
ht[v]=2*n;
for(i=0;i<deg[v];i++) {
u=adj[v][i];
if(res[v][u]) ht[v]=min(ht[u]+1,ht[v]);
}
}
inline void initPreflow() {
int i,u;
lst.clear();
for(i=0;i<n;i++) {
ht[i]=ef[i]=0; apt[i]=0;
if(i!=src&&i!=sink) lst.push_back(i);
}
ht[src]=n;
for(i=0;i<deg[src];i++) {
u=adj[src][i];
ef[u]=res[src][u];
ef[src]-=ef[u];
res[u][src]=ef[u];
res[src][u]=0;
}
}
inline void discharge(int v) {
int u;
while(ef[v]) {
if(apt[v]==deg[v]) {
relabel(v);
apt[v]=0;
continue;
}
u=adj[v][apt[v]];
if(res[v][u]&&ht[v]==ht[u]+1) push(v,u);
else apt[v]++;
}
}
inline void relabelToFront() {
int oldh,v;
list<int>::iterator it;
initPreflow();
for(it=lst.begin();it!=lst.end();it++) {
v=*it; oldh=ht[v]; discharge(v);
if(ht[v]>oldh) {
lst.push_front(v);
lst.erase(it);
it=lst.begin();
}
}
}