namespace MCMF {
int S, T;//源点,汇点
int tot, n;
int st, en, maxflow, mincost;
bool vis[MX];
int head[MX], cur[MX], dis[MX];
int roade[MX], roadv[MX], rsz; //用于打印路径
const int ME = 4e5 + 5;//边的数量
queue <int> Q;
struct Edge {
int v, cap, cost, nxt, flow;
Edge() {}
Edge(int a, int b, int c, int d) {
v = a, cap = b, cost = c, nxt = d, flow = 0;
}
} E[ME], SE[ME];
void init(int _n) {
n = _n, tot = 0;
for(int i = 0; i <= n; i++) head[i] = -1;
}
void edge_add(int u, int v, int cap, int cost) {
E[tot] = Edge(v, cap, cost, head[u]);
head[u] = tot++;
E[tot] = Edge(u, 0, -cost, head[v]);
head[v] = tot++;
}
bool adjust() {
int v, min = INF;
for(int i = 0; i <= n; i++) {
if(!vis[i]) continue;
for(int j = head[i]; ~j; j = E[j].nxt) {
v = E[j].v;
if(E[j].cap - E[j].flow) {
if(!vis[v] && dis[v] - dis[i] + E[j].cost < min) {
min = dis[v] - dis[i] + E[j].cost;
}
}
}
}
if(min == INF) return false;
for(int i = 0; i <= n; i++) {
if(vis[i]) {
cur[i] = head[i];
vis[i] = false;
dis[i] += min;
}
}
return true;
}
int augment(int i, int flow) {
if(i == en) {
mincost += dis[st] * flow;
maxflow += flow;
return flow;
}
vis[i] = true;
for(int j = cur[i]; j != -1; j = E[j].nxt) {
int v = E[j].v;
if(E[j].cap == E[j].flow) continue;
if(vis[v] || dis[v] + E[j].cost != dis[i]) continue;
int delta = augment(v, std::min(flow, E[j].cap - E[j].flow));
if(delta) {
E[j].flow += delta;
E[j ^ 1].flow -= delta;
cur[i] = j;
return delta;
}
}
return 0;
}
void spfa() {
int u, v;
for(int i = 0; i <= n; i++) {
vis[i] = false;
dis[i] = INF;
}
Q.push(st);
dis[st] = 0; vis[st] = true;
while(!Q.empty()) {
u = Q.front(), Q.pop(); vis[u] = false;
for(int i = head[u]; ~i; i = E[i].nxt) {
v = E[i].v;
if(E[i].cap == E[i].flow || dis[v] <= dis[u] + E[i].cost) continue;
dis[v] = dis[u] + E[i].cost;
if(!vis[v]) {
vis[v] = true;
Q.push(v);
}
}
}
for(int i = 0; i <= n; i++) {
dis[i] = dis[en] - dis[i];
}
// spfa_time_total++;
}
int zkw(int s, int t, int &ret_flow) {
st = s, en = t;
spfa();
mincost = maxflow = 0;
for(int i = 0; i <= n; i++) {
vis[i] = false;
cur[i] = head[i];
}
do {
while(augment(st, INF)) {
memset(vis, false, n * sizeof(bool));
}
} while(adjust());
ret_flow = maxflow;
return mincost;
}
}
模板_zkw费用流
最新推荐文章于 2021-02-22 11:56:00 发布