SAP算法:最大流
// ALGORITHM_MAXFLOW_SAP -> #ifdef ALGORITHM_MAXFLOW_SAP_ENABLED #define ALGORITHM_MAXFLOW_SAP_MAXN 20010 #define ALGORITHM_MAXFLOW_SAP_MAXM 880010 #define ALGORITHM_MAXFLOW_SAP_INF 0x7FFFFFFF struct ALGORITHM_MAXFLOW_SAP_Node { int from, to, next; int cap; } ALGORITHM_MAXFLOW_SAP_edge[ALGORITHM_MAXFLOW_SAP_MAXM]; int ALGORITHM_MAXFLOW_SAP_tol; int ALGORITHM_MAXFLOW_SAP_head[ALGORITHM_MAXFLOW_SAP_MAXN]; int ALGORITHM_MAXFLOW_SAP_dep[ALGORITHM_MAXFLOW_SAP_MAXN]; int ALGORITHM_MAXFLOW_SAP_gap[ALGORITHM_MAXFLOW_SAP_MAXN]; int ALGORITHM_MAXFLOW_SAP_cur[ALGORITHM_MAXFLOW_SAP_MAXN]; int ALGORITHM_MAXFLOW_SAP_S[ALGORITHM_MAXFLOW_SAP_MAXN]; int ALGORITHM_MAXFLOW_SAP_que[ALGORITHM_MAXFLOW_SAP_MAXN]; int ALGORITHM_MAXFLOW_SAP_n; void ALGORITHM_MAXFLOW_SAP_clear() { ALGORITHM_MAXFLOW_SAP_tol = 0; memset(ALGORITHM_MAXFLOW_SAP_head, -1, sizeof(ALGORITHM_MAXFLOW_SAP_head)); } void ALGORITHM_MAXFLOW_SAP_addedge(int u, int v, int w) { ALGORITHM_MAXFLOW_SAP_edge[ALGORITHM_MAXFLOW_SAP_tol].from = u; ALGORITHM_MAXFLOW_SAP_edge[ALGORITHM_MAXFLOW_SAP_tol].to = v; ALGORITHM_MAXFLOW_SAP_edge[ALGORITHM_MAXFLOW_SAP_tol].cap = w; ALGORITHM_MAXFLOW_SAP_edge[ALGORITHM_MAXFLOW_SAP_tol].next = ALGORITHM_MAXFLOW_SAP_head[u]; ALGORITHM_MAXFLOW_SAP_head[u] = ALGORITHM_MAXFLOW_SAP_tol++; ALGORITHM_MAXFLOW_SAP_edge[ALGORITHM_MAXFLOW_SAP_tol].from = v; ALGORITHM_MAXFLOW_SAP_edge[ALGORITHM_MAXFLOW_SAP_tol].to = u; ALGORITHM_MAXFLOW_SAP_edge[ALGORITHM_MAXFLOW_SAP_tol].cap = 0; ALGORITHM_MAXFLOW_SAP_edge[ALGORITHM_MAXFLOW_SAP_tol].next = ALGORITHM_MAXFLOW_SAP_head[v]; ALGORITHM_MAXFLOW_SAP_head[v] = ALGORITHM_MAXFLOW_SAP_tol++; } void ALGORITHM_MAXFLOW_SAP_BFS(int start, int end) { memset(ALGORITHM_MAXFLOW_SAP_dep, -1, sizeof(ALGORITHM_MAXFLOW_SAP_dep)); memset(ALGORITHM_MAXFLOW_SAP_gap, 0, sizeof(ALGORITHM_MAXFLOW_SAP_gap)); ALGORITHM_MAXFLOW_SAP_gap[0] = 1; int front, rear; front = rear = 0; ALGORITHM_MAXFLOW_SAP_dep[end] = 0; ALGORITHM_MAXFLOW_SAP_que[rear++] = end; while (front != rear) { int u = ALGORITHM_MAXFLOW_SAP_que[front++]; if (front == ALGORITHM_MAXFLOW_SAP_MAXN) { front = 0; } for (int i = ALGORITHM_MAXFLOW_SAP_head[u]; i != -1; i = ALGORITHM_MAXFLOW_SAP_edge[i].next) { int v = ALGORITHM_MAXFLOW_SAP_edge[i].to; if (ALGORITHM_MAXFLOW_SAP_dep[v] != -1) { continue; } ALGORITHM_MAXFLOW_SAP_que[rear++] = v; if (rear == ALGORITHM_MAXFLOW_SAP_MAXN) { rear = 0; } ALGORITHM_MAXFLOW_SAP_dep[v] = ALGORITHM_MAXFLOW_SAP_dep[u] + 1; ++ALGORITHM_MAXFLOW_SAP_gap[ALGORITHM_MAXFLOW_SAP_dep[v]]; } } } int ALGORITHM_MAXFLOW_SAP_SAP(int start, int end) { int res = 0; ALGORITHM_MAXFLOW_SAP_BFS(start, end); int top = 0; memcpy(ALGORITHM_MAXFLOW_SAP_cur, ALGORITHM_MAXFLOW_SAP_head, sizeof(ALGORITHM_MAXFLOW_SAP_head)); int u = start; int i; while (ALGORITHM_MAXFLOW_SAP_dep[start] < ALGORITHM_MAXFLOW_SAP_n) { if (u == end) { int temp = ALGORITHM_MAXFLOW_SAP_INF; int inser; for (i = 0; i < top; i++) if (temp > ALGORITHM_MAXFLOW_SAP_edge[ALGORITHM_MAXFLOW_SAP_S[i]].cap) { temp = ALGORITHM_MAXFLOW_SAP_edge[ALGORITHM_MAXFLOW_SAP_S[i]].cap; inser = i; } for (i = 0; i < top; i++) { ALGORITHM_MAXFLOW_SAP_edge[ALGORITHM_MAXFLOW_SAP_S[i]].cap -= temp; ALGORITHM_MAXFLOW_SAP_edge[ALGORITHM_MAXFLOW_SAP_S[i] ^ 1].cap += temp; } res += temp; top = inser; u = ALGORITHM_MAXFLOW_SAP_edge[ALGORITHM_MAXFLOW_SAP_S[top]].from; } if (u != end && ALGORITHM_MAXFLOW_SAP_gap[ALGORITHM_MAXFLOW_SAP_dep[u] - 1] == 0) { break; } for (i = ALGORITHM_MAXFLOW_SAP_cur[u]; i != -1; i = ALGORITHM_MAXFLOW_SAP_edge[i].next) if (ALGORITHM_MAXFLOW_SAP_edge[i].cap != 0 && ALGORITHM_MAXFLOW_SAP_dep[u] == ALGORITHM_MAXFLOW_SAP_dep[ALGORITHM_MAXFLOW_SAP_edge[i].to] + 1) { break; } if (i != -1) { ALGORITHM_MAXFLOW_SAP_cur[u] = i; ALGORITHM_MAXFLOW_SAP_S[top++] = i; u = ALGORITHM_MAXFLOW_SAP_edge[i].to; } else { int min = ALGORITHM_MAXFLOW_SAP_n; for (i = ALGORITHM_MAXFLOW_SAP_head[u]; i != -1; i = ALGORITHM_MAXFLOW_SAP_edge[i].next) { if (ALGORITHM_MAXFLOW_SAP_edge[i].cap == 0) { continue; } if (min > ALGORITHM_MAXFLOW_SAP_dep[ALGORITHM_MAXFLOW_SAP_edge[i].to]) { min = ALGORITHM_MAXFLOW_SAP_dep[ALGORITHM_MAXFLOW_SAP_edge[i].to]; ALGORITHM_MAXFLOW_SAP_cur[u] = i; } } --ALGORITHM_MAXFLOW_SAP_gap[ALGORITHM_MAXFLOW_SAP_dep[u]]; ALGORITHM_MAXFLOW_SAP_dep[u] = min + 1; ++ALGORITHM_MAXFLOW_SAP_gap[ALGORITHM_MAXFLOW_SAP_dep[u]]; if (u != start) { u = ALGORITHM_MAXFLOW_SAP_edge[ALGORITHM_MAXFLOW_SAP_S[--top]].from; } } } return res; } #endif // <- ALGORITHM_MAXFLOW_SAP
#define ALGORITHM_MAXFLOW_SAP_ENABLED 允许SAP算法进行编译
ALGORITHM_MAXFLOW_SAP_MAXN 点的最大数目
ALGORITHM_MAXFLOW_SAP_MAXM 边的最大数目
ALGORITHM_MAXFLOW_SAP_n 点的数目
ALGORITHM_MAXFLOW_SAP_clear() 清空数据结构
ALGORITHM_MAXFLOW_SAP_addedge(u,v,w) 添加一条从u到v容量为w的弧
ALGORITHM_MAXFLOW_SAP_SAP(s,t) 从s到t的最大流
类实现:
class MaxFlow_SAP { public: #define SAP_MAXN 20010 #define SAP_MAXM 880010 #define SAP_INF 0x3FFFFFFF struct Node { int from, to, next; int cap; } edge[SAP_MAXM]; int tol; int head[SAP_MAXN]; int dep[SAP_MAXN]; int gap[SAP_MAXN]; int cur[SAP_MAXN]; int S[SAP_MAXN]; int que[SAP_MAXN]; int n; MaxFlow_SAP() { clear(); } void clear() { tol = 0; memset(head, -1, sizeof(head)); } void addedge(int u, int v, int w) { edge[tol].from = u; edge[tol].to = v; edge[tol].cap = w; edge[tol].next = head[u]; head[u] = tol++; edge[tol].from = v; edge[tol].to = u; edge[tol].cap = 0; edge[tol].next = head[v]; head[v] = tol++; } void BFS(int start, int end) { memset(dep, -1, sizeof(dep)); memset(gap, 0, sizeof(gap)); gap[0] = 1; int front, rear; front = rear = 0; dep[end] = 0; que[rear++] = end; while (front != rear) { int u = que[front++]; if (front == SAP_MAXN) { front = 0; } for (int i = head[u]; i != -1; i = edge[i].next) { int v = edge[i].to; if (dep[v] != -1) { continue; } que[rear++] = v; if (rear == SAP_MAXN) { rear = 0; } dep[v] = dep[u] + 1; ++gap[dep[v]]; } } } int SAP(int start, int end) { int res = 0; BFS(start, end); int top = 0; memcpy(cur, head, sizeof(head)); int u = start; int i; while (dep[start] < n) { if (u == end) { int temp = SAP_INF; int inser; for (i = 0; i < top; i++) if (temp > edge[S[i]].cap) { temp = edge[S[i]].cap; inser = i; } for (i = 0; i < top; i++) { edge[S[i]].cap -= temp; edge[S[i] ^ 1].cap += temp; } res += temp; top = inser; u = edge[S[top]].from; } if (u != end && gap[dep[u] - 1] == 0) { break; } for (i = cur[u]; i != -1; i = edge[i].next) if (edge[i].cap != 0 && dep[u] == dep[edge[i].to] + 1) { break; } if (i != -1) { cur[u] = i; S[top++] = i; u = edge[i].to; } else { int min = n; for (i = head[u]; i != -1; i = edge[i].next) { if (edge[i].cap == 0) { continue; } if (min > dep[edge[i].to]) { min = dep[edge[i].to]; cur[u] = i; } } --gap[dep[u]]; dep[u] = min + 1; ++gap[dep[u]]; if (u != start) { u = edge[S[--top]].from; } } } return res; } };
最小费用最大流
//ALGORITHM MINCOSTFLOW ->
#define ALGORITHM_MINCOSTFLOW_MAXN 600
#define ALGORITHM_MINCOSTFLOW_MAXM 360000
#define ALGORITHM_MINCOSTFLOW_INF 0X7FFFFFFF
struct ALGORITHM_MINCOSTFLOW_Edge {
int v;
int val;
int cost;
int next;
} ALGORITHM_MINCOSTFLOW_edge[ALGORITHM_MINCOSTFLOW_MAXM];
int ALGORITHM_MINCOSTFLOW_head[ALGORITHM_MINCOSTFLOW_MAXN];
int ALGORITHM_MINCOSTFLOW_countedge;
int ALGORITHM_MINCOSTFLOW_pre[ALGORITHM_MINCOSTFLOW_MAXN];
int ALGORITHM_MINCOSTFLOW_pos[ALGORITHM_MINCOSTFLOW_MAXN];
int ALGORITHM_MINCOSTFLOW_dis[ALGORITHM_MINCOSTFLOW_MAXN];
int ALGORITHM_MINCOSTFLOW_que[ALGORITHM_MINCOSTFLOW_MAXM];
bool ALGORITHM_MINCOSTFLOW_vis[ALGORITHM_MINCOSTFLOW_MAXN];
void ALGORITHM_MINCOSTFLOW_addedge(int u, int v, int val, int cost) {
ALGORITHM_MINCOSTFLOW_edge[ALGORITHM_MINCOSTFLOW_countedge].v = v;
ALGORITHM_MINCOSTFLOW_edge[ALGORITHM_MINCOSTFLOW_countedge].val = val;
ALGORITHM_MINCOSTFLOW_edge[ALGORITHM_MINCOSTFLOW_countedge].cost = cost;
ALGORITHM_MINCOSTFLOW_edge[ALGORITHM_MINCOSTFLOW_countedge].next = ALGORITHM_MINCOSTFLOW_head[u];
ALGORITHM_MINCOSTFLOW_head[u] = ALGORITHM_MINCOSTFLOW_countedge++;
ALGORITHM_MINCOSTFLOW_edge[ALGORITHM_MINCOSTFLOW_countedge].v = u;
ALGORITHM_MINCOSTFLOW_edge[ALGORITHM_MINCOSTFLOW_countedge].val = 0;
ALGORITHM_MINCOSTFLOW_edge[ALGORITHM_MINCOSTFLOW_countedge].cost = -cost;
ALGORITHM_MINCOSTFLOW_edge[ALGORITHM_MINCOSTFLOW_countedge].next = ALGORITHM_MINCOSTFLOW_head[v];
ALGORITHM_MINCOSTFLOW_head[v] = ALGORITHM_MINCOSTFLOW_countedge++;
}
void ALGORITHM_MINCOSTFLOW_clear() {
memset(ALGORITHM_MINCOSTFLOW_head, -1, sizeof(ALGORITHM_MINCOSTFLOW_head));
ALGORITHM_MINCOSTFLOW_countedge = 0;
}
bool ALGORITHM_MINCOSTFLOW_spfa(int s, int t) {
memset(ALGORITHM_MINCOSTFLOW_pre, -1, sizeof(ALGORITHM_MINCOSTFLOW_pre));
memset(ALGORITHM_MINCOSTFLOW_vis, 0, sizeof(ALGORITHM_MINCOSTFLOW_vis));
int Head, tail;
Head = tail = 0;
for (int i = 0; i < ALGORITHM_MINCOSTFLOW_MAXN; i++) {
ALGORITHM_MINCOSTFLOW_dis[i] = ALGORITHM_MINCOSTFLOW_INF;
}
ALGORITHM_MINCOSTFLOW_que[tail++] = s;
ALGORITHM_MINCOSTFLOW_pre[s] = s;
ALGORITHM_MINCOSTFLOW_dis[s] = 0;
ALGORITHM_MINCOSTFLOW_vis[s] = 1;
while (Head != tail) {
int now = ALGORITHM_MINCOSTFLOW_que[Head++];
ALGORITHM_MINCOSTFLOW_vis[now] = 0;
for (int i = ALGORITHM_MINCOSTFLOW_head[now]; i != -1; i = ALGORITHM_MINCOSTFLOW_edge[i].next) {
int adj = ALGORITHM_MINCOSTFLOW_edge[i].v;
if (ALGORITHM_MINCOSTFLOW_edge[i].val > 0 && ALGORITHM_MINCOSTFLOW_dis[now] + ALGORITHM_MINCOSTFLOW_edge[i].cost < ALGORITHM_MINCOSTFLOW_dis[adj]) {
ALGORITHM_MINCOSTFLOW_dis[adj] = ALGORITHM_MINCOSTFLOW_dis[now] + ALGORITHM_MINCOSTFLOW_edge[i].cost;
ALGORITHM_MINCOSTFLOW_pre[adj] = now;
ALGORITHM_MINCOSTFLOW_pos[adj] = i;
if (!ALGORITHM_MINCOSTFLOW_vis[adj]) {
ALGORITHM_MINCOSTFLOW_vis[adj] = 1;
ALGORITHM_MINCOSTFLOW_que[tail++] = adj;
}
}
}
}
return ALGORITHM_MINCOSTFLOW_pre[t] != -1;
}
int ALGORITHM_MINCOSTFLOW_MinCostFlow(int s, int t) {
int cost = 0, flow = 0;
while (ALGORITHM_MINCOSTFLOW_spfa(s, t)) {
int f = ALGORITHM_MINCOSTFLOW_INF;
for (int i = t; i != s; i = ALGORITHM_MINCOSTFLOW_pre[i])
if (ALGORITHM_MINCOSTFLOW_edge[ALGORITHM_MINCOSTFLOW_pos[i]].val < f) {
f = ALGORITHM_MINCOSTFLOW_edge[ALGORITHM_MINCOSTFLOW_pos[i]].val;
}
flow += f;
cost += ALGORITHM_MINCOSTFLOW_dis[t] * f;
for (int i = t; i != s; i = ALGORITHM_MINCOSTFLOW_pre[i]) {
ALGORITHM_MINCOSTFLOW_edge[ALGORITHM_MINCOSTFLOW_pos[i]].val -= f;
ALGORITHM_MINCOSTFLOW_edge[ALGORITHM_MINCOSTFLOW_pos[i] ^ 1].val += f;
}
}
return cost;
}
// <- ALGORITHM MINCOSTFLOW
ALGORITHM_MINCOSTFLOW_MAXN 点的最大数目
ALGORITHM_MINCOSTFLOW_MAXM 边的最大数目
ALGORITHM_MINCOSTFLOW_clear() 清空数据结构
ALGORITHM_MINCOSTFLOW_addedge(u,v,val,cost) 增加从u到v,容量为val,费用为cost的弧
ALGORITHM_MINCOSTFLOW_MinCostFlow(s,t) 从s到t的最小费用最大流