先贴代码
最大流-Dinic
struct Max_Flow { struct Edge { int from, to, cap, flow; }; std::vector<Edge> edges; std::vector<int> G[N]; int level[N], cur[N]; int n, m, s, t; void init(int n) { this->n = n; for (int i=0; i<=n; ++i) { G[i].clear (); } edges.clear (); } void add_edge(int from, int to, int cap) { edges.push_back ((Edge) {from, to, cap, 0}); edges.push_back ((Edge) {to, from, 0, 0}); m = edges.size (); G[from].push_back (m - 2); G[to].push_back (m - 1); } bool BFS() { std::fill (level, level+1+n, -1); std::queue<int> que; level[s] = 0; que.push (s); while (!que.empty ()) { int u = que.front (); que.pop (); for (int i=0; i<G[u].size (); ++i) { Edge &e = edges[G[u][i]]; if (level[e.to] == -1 && e.cap > e.flow) { level[e.to] = level[u] + 1; que.push (e.to); } } } return level[t] != -1; } int DFS(int u, int a) { if (u == t || a == 0) { return a; } int flow = 0, f; for (int &i=cur[u]; i<G[u].size (); ++i) { Edge &e = edges[G[u][i]]; if (level[u] + 1 == level[e.to] && (f = DFS (e.to, std::min (a, e.cap - e.flow))) > 0) { e.flow += f; edges[G[u][i]^1].flow -= f; flow += f; a -= f; if (a == 0) { break; } } } return flow; } int Dinic(int s, int t) { this->s = s; this->t = t; int flow = 0; while (BFS ()) { std::fill (cur, cur+1+n, 0); flow += DFS (s, INF); } return flow; } };
最小费用最大流(SPFA)
struct Min_Cost_Max_Flow { struct Edge { int from, to, cap, flow, cost; }; std::vector<Edge> edges; std::vector<int> G[N]; bool vis[N]; int d[N], p[N], a[N]; int n, m, s, t; void init(int n) { this->n = n; for (int i=0; i<=n; ++i) { G[i].clear (); } edges.clear (); } void add_edge(int from, int to, int cap, int cost) { edges.push_back ((Edge) {from, to, cap, 0, cost}); edges.push_back ((Edge) {to, from, 0, 0, -cost}); m = edges.size (); G[from].push_back (m - 2); G[to].push_back (m - 1); } bool SPFA(int &flow, int &cost) { memset (d, INF, sizeof (d)); memset (vis, false, sizeof (vis)); memset (p, -1, sizeof (p)); d[s] = 0; vis[s] = true; p[s] = 0; a[s] = INF; std::queue<int> que; que.push (s); while (!que.empty ()) { int u = que.front (); que.pop (); vis[u] = false; for (int i=0; i<G[u].size (); ++i) { Edge &e = edges[G[u][i]]; if (e.cap > e.flow && d[e.to] > d[u] + e.cost) { d[e.to] = d[u] + e.cost; p[e.to] = G[u][i]; a[e.to] = std::min (a[u], e.cap - e.flow); if (!vis[e.to]) { vis[e.to] = true; que.push (e.to); } } } } if (d[t] == INF) { return false; } flow += a[t]; cost += d[t] * a[t]; int u = t; while (u != s) { edges[p[u]].flow += a[t]; edges[p[u]^1].flow -= a[t]; u = edges[p[u]].from; } return true; } void run(int s, int t, int &flow, int &cost) { this->s = s; this->t = t; flow = cost = 0; while (SPFA (flow, cost)); } };