Skip to content

Commit 1e763a4

Browse files
committed
rewrite cost flow code
1 parent 629d89d commit 1e763a4

File tree

1 file changed

+141
-96
lines changed

1 file changed

+141
-96
lines changed

graph-utility/CostFlow.cc

Lines changed: 141 additions & 96 deletions
Original file line numberDiff line numberDiff line change
@@ -1,128 +1,173 @@
11
#include <bits/stdc++.h>
2-
// 首先调用MCMF::init()设置点的个数,源点和汇点
3-
// 调用MCMF::addedge()加边
4-
// 调用MCMF::solve()计算答案,答案存在MinCost和MaxFlow里面
5-
namespace MCMF {
6-
typedef int flow_t;
7-
typedef int cost_t;
8-
const int MAXN = 200, MAXM = 100000;
2+
3+
template<typename flow_t, typename cost_t>
4+
struct MCMF {
5+
static const int N = 200, M = 100000;
96
const flow_t inf = 1e9;
10-
struct Edge {
11-
int from, to, nx;
7+
struct node {
8+
int from, to, nxt;
129
flow_t cap, flow;
1310
cost_t cost;
14-
Edge() {}
15-
Edge(int _from, int _to, int _nx, flow_t _cap, cost_t _cost):
16-
from(_from), to(_to), nx(_nx), cap(_cap), flow(0), cost(_cost) {}
17-
} E[MAXM];
18-
cost_t dis[MAXN];
19-
int G[MAXN], pre[MAXN], vis[MAXN];
20-
int sz, N; //S源点, T汇点
11+
node() {}
12+
node(int from, int to, int nxt, flow_t cap, cost_t cost):
13+
from(from), to(to), nxt(nxt), cap(cap), flow(0), cost(cost) {}
14+
} E[M];
15+
cost_t dis[N];
16+
int G[N], pre[N], vis[N], n, m;
2117
void init(int n) {
22-
memset(G, -1, sizeof(G[0]) * n);
23-
sz = 0; N = n;
18+
this->n = n;
19+
this->m = 0;
20+
std::fill(G, G + n, -1);
2421
}
25-
void addedge(int u, int v, flow_t f, cost_t c) {//u -> v
26-
E[sz] = Edge(u, v, G[u], f, +c); G[u] = sz++;
27-
E[sz] = Edge(v, u, G[v], 0, -c); G[v] = sz++;
22+
void link(int u, int v, flow_t f, cost_t c) {
23+
E[m] = node(u, v, G[u], f, +c); G[u] = m++;
24+
E[m] = node(v, u, G[v], 0, -c); G[v] = m++;
2825
}
2926
bool extand(int S, int T) {
30-
std::queue<int> Q;
31-
memset(vis, 0, sizeof(vis[0]) * N);
32-
memset(pre, -1, sizeof(pre[0]) * N);
33-
for (int i = 0; i < N; ++i) dis[i] = inf;
34-
Q.push(S); vis[S] = 1; dis[S] = 0;
35-
while (!Q.empty()) {
36-
int u = Q.front();
37-
Q.pop(); vis[u]=0;
38-
for (int it = G[u]; ~it; it = E[it].nx) {
27+
std::fill(vis, vis + n, 0);
28+
std::fill(dis, dis + n, inf);
29+
std::queue<int> queue;
30+
dis[S] = 0;
31+
queue.push(S);
32+
for (; !queue.empty(); queue.pop()) {
33+
int u = queue.front();
34+
vis[u] = false;
35+
for (int it = G[u]; ~it; it = E[it].nxt) {
3936
int v = E[it].to;
4037
if (E[it].cap > E[it].flow && dis[v] > dis[u] + E[it].cost) {
41-
dis[v] = dis[u] + E[it].cost, pre[v] = it;
42-
if (!vis[v]) Q.push(v), vis[v] = true;
38+
dis[v] = dis[u] + E[it].cost;
39+
pre[v] = it;
40+
if (!vis[v]) queue.push(v);
41+
vis[v] = true;
4342
}
4443
}
4544
}
4645
return dis[T] < inf; // 改成dis[T] <= 0 求可行流
4746
}
48-
std::pair<flow_t, cost_t> solve(int S, int T) {
49-
flow_t MaxFlow = 0;
50-
cost_t MinCost = 0;
47+
std::pair<flow_t, cost_t> run(int S, int T) {
48+
flow_t max_flow = 0;
49+
cost_t min_cost = 0;
5150
while (extand(S, T)) {
52-
flow_t aug = inf;
53-
for (int it = pre[T]; ~it; it = pre[E[it].from]) {
54-
aug = std::min(aug, E[it].cap - E[it].flow);
51+
flow_t delta = inf;
52+
for (int u = T; u != S; u = E[pre[u]].from) {
53+
delta = std::min(delta, E[pre[u]].cap - E[pre[u]].flow);
5554
}
56-
MinCost += aug * dis[T], MaxFlow += aug;
57-
for (int it = pre[T]; ~it; it = pre[E[it].from]) {
58-
E[it].flow += aug, E[it ^ 1].flow -= aug;
55+
min_cost += delta * dis[T];
56+
max_flow += delta;
57+
for (int u = T; u != S; u = E[pre[u]].from) {
58+
E[pre[u]].flow += delta;
59+
E[pre[u] ^ 1].flow -= delta;
5960
}
6061
}
61-
return std::make_pair(MaxFlow, MinCost);
62+
return {max_flow, min_cost};
6263
}
63-
}
64+
};
6465

65-
namespace ZKW {
66-
const int MAXN = 50000 + 10, MAXM = 300000, inf = 1e9;
67-
typedef int VAL;
68-
struct Edge {
69-
int v,f;
70-
VAL c;
71-
int nx;
72-
Edge() {}
73-
Edge(int v,int f,VAL c,int nx):v(v),f(f),c(c),nx(nx) {}
74-
} E[MAXM];
75-
int G[MAXN], Q[MAXN];
76-
VAL dis[MAXN],mincost;
77-
bool vis[MAXN],mark[MAXN];
78-
int N,S,T,sz;
79-
void init(int _n, int _s, int _t) {
80-
N = _n; S = _s; T = _t; sz = 0;
81-
memset(G, -1, sizeof(G[0]) * N);
66+
template<typename flow_t, typename cost_t>
67+
struct MCMF_ZKW {
68+
static const int N = 200, M = 3000, inf = 1e9;
69+
struct node {
70+
int to, nxt;
71+
flow_t cap, flow;
72+
cost_t cost;
73+
node() {}
74+
node(int to, int nxt, flow_t cap, cost_t cost):
75+
to(to), nxt(nxt), cap(cap), flow(0), cost(cost) {}
76+
} E[M];
77+
int G[N], n, m;
78+
cost_t min_cost, len;
79+
flow_t max_flow;
80+
bool done[N];
81+
void init(int n) {
82+
this->n = n;
83+
this->m = 0;
84+
std::fill(G, G + n, -1);
8285
}
83-
void link(int u, int v, int f, VAL c) {
84-
E[sz]=Edge(v,f,+c,G[u]); G[u]=sz++;
85-
E[sz]=Edge(u,0,-c,G[v]); G[v]=sz++;
86+
void link(int u, int v, flow_t f, cost_t c) {
87+
E[m] = node(v, G[u], f, +c); G[u] = m++;
88+
E[m] = node(u, G[v], 0, -c); G[v] = m++;
8689
}
87-
bool spfa() {
88-
for (int i=0;i<N;++i) dis[i]=inf,vis[i]=0;
89-
dis[T]=0; Q[0]=T; vis[T]=1;
90-
for (int h=0,t=1;h!=t; ) {
91-
int u=Q[h++],v; vis[u]=false;
92-
if (h==MAXN) h=0;
93-
for (int it=G[u];~it;it=E[it].nx) {
94-
if (dis[u]-E[it].c<dis[v=E[it].v]&&E[it^1].f) {
95-
dis[v]=dis[u]-E[it].c;
96-
if (!vis[v]) {
97-
vis[v]=true; Q[t++]=v;
98-
if (t==MAXN) t=0;
99-
}
100-
}
90+
flow_t aug(int now, int T, flow_t max_cap) {
91+
if (now == T) {
92+
max_flow += max_cap;
93+
min_cost += max_cap * len;
94+
return max_cap;
95+
}
96+
done[now] = true;
97+
flow_t upp = max_cap;
98+
for (int it = G[now]; ~it && upp; it = E[it].nxt) {
99+
if (E[it].cap > E[it].flow && !E[it].cost && !done[E[it].to]) {
100+
flow_t delta = aug(E[it].to, T, std::min(upp, E[it].cap - E[it].flow));
101+
E[it].flow += delta;
102+
E[it ^ 1].flow -= delta;
103+
upp -= delta;
101104
}
102105
}
103-
return dis[S]!=inf;
106+
return max_cap - upp;
104107
}
105-
int dfs(int u, int low) {
106-
mark[u]=true; if (u==T) return low;
107-
int ret=0,tmp=0;
108-
for (int it=G[u],v;~it&&ret<low;it=E[it].nx) {
109-
if (E[it].f&&!mark[v=E[it].v]&&dis[u]-E[it].c==dis[v]) {
110-
tmp=dfs(v,std::min(E[it].f,low-ret));
111-
E[it].f-=tmp; E[it^1].f+=tmp;
112-
mincost+=E[it].c*tmp; ret+=tmp;
108+
bool label(int S, int T) {//不能用于负费用
109+
cost_t delta = inf;
110+
for (int u = 0; u < n; ++u) if (done[u]) {
111+
for (int it = G[u]; ~it; it = E[it].nxt) {
112+
if (E[it].cap > E[it].flow && !done[E[it].to]) {
113+
delta = std::min(delta, E[it].cost);
114+
}
115+
}
116+
}
117+
if (delta == inf) return false;
118+
for (int u = 0; u < n; ++u) if (done[u]) {
119+
for (int it = G[u]; ~it; it = E[it].nxt) {
120+
E[it].cost -= delta;
121+
E[it ^ 1].cost += delta;
113122
}
114123
}
115-
return ret;
124+
len += delta;
125+
return true;
116126
}
117-
VAL solve() {
118-
int maxflow = 0; mincost = 0;
119-
while (spfa()) {
120-
mark[T] = true;
121-
while (mark[T]) {
122-
memset(mark, 0, sizeof(mark[0]) * N);
123-
maxflow += dfs(S, inf);
127+
cost_t dis[N];
128+
bool label_primal_dual(int S, int T) {
129+
for (int i = 0; i < n; ++i) dis[i] = inf;
130+
std::fill(done, done + n, 0);
131+
dis[T] = 0;
132+
std::queue<int> queue;
133+
queue.push(T);
134+
for (; !queue.empty(); queue.pop()) {
135+
int u = queue.front();
136+
done[u] = false;
137+
for (int it = G[u]; ~it; it = E[it].nxt) {
138+
int v = E[it].to;
139+
cost_t cost = dis[u] - E[it].cost;
140+
if (E[it ^ 1].cap > E[it ^ 1].flow && cost < dis[v]) {
141+
dis[v] = cost;
142+
if (!done[v]) queue.push(v);
143+
done[v] = true;
144+
}
145+
}
146+
}
147+
for (int u = 0; u < n; ++u) {
148+
for (int it = G[u]; ~it; it = E[it].nxt) {
149+
E[it].cost += dis[E[it].to] - dis[u];
124150
}
125151
}
126-
return mincost;
152+
len += dis[S];
153+
return dis[S] < inf;
154+
}
155+
std::pair<flow_t, cost_t> run_primal_dual(int S, int T) {
156+
max_flow = min_cost = len = 0;
157+
while (label_primal_dual(S, T)) {
158+
do {
159+
std::fill(done, done + n, 0);
160+
} while (aug(S, T, inf));
161+
}
162+
return {max_flow, min_cost};
163+
}
164+
std::pair<flow_t, cost_t> run(int S, int T) {
165+
max_flow = min_cost = len = 0;
166+
do {
167+
do {
168+
std::fill(done, done + n, 0);
169+
} while (aug(S, T, inf));
170+
} while (label_primal_dual(S, T));
171+
return {max_flow, min_cost};
127172
}
128-
}
173+
};

0 commit comments

Comments
 (0)