ISAP 最大流 赛事首选
无向图将反向边权值改为v即可。
#include<bits/stdc++.h>
using namespace std;
const int oo = 0x7f7f7f7f;
const int N = 10010;
const int M = 100010;
template <typename T>
T read(){
T n(0), f(1);
char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
for(; isdigit(ch); ch = getchar()) n = n*10 + ch-48;
return n*f;
}
#define read() read<int>()
int n, m, e, S, T;
int to[M<<1], nxt[M<<1], w[M<<1];
int Begin[N], h[N], gap[N];
void addedge(int x, int y, int v){
to[e] = y; nxt[e] = Begin[x]; w[e] = v; Begin[x] = e++;
to[e] = x; nxt[e] = Begin[y]; w[e] = 0; Begin[y] = e++;
}
int dfs(int u, int cost){
if(u == T) return cost;
int minh = n-1, lv = cost, d;
for(int i = Begin[u]; i != -1; i = nxt[i]){
int v = to[i], val = w[i];
if(val > 0){
if(h[v] + 1 == h[u]){
d = min(lv, val);
d = dfs(v, d);
w[i] -= d;
w[i^1] += d;
lv -= d;
if(h[S] >= n) return cost-lv;
if(!lv) break;
}
minh = min(minh, h[v]);
}
}
if(lv == cost){
--gap[h[u]];
if(!gap[h[u]]) h[S] = n;
h[u] = minh+1;
++gap[h[u]];
}
return cost-lv;
}
int sap(int s, int t){
S = s; T = t;
memset(gap, 0, sizeof(gap));
memset(h, 0, sizeof(h));
gap[s] = n;
int ret = 0;
while(h[s] < n){
ret += dfs(s, oo);
}
return ret;
}
int main(){
memset(Begin, -1, sizeof(Begin));
int s, t;
n = read(); m = read();
s = read(); t = read();
for(int i = 1; i <= m; ++i){
int x, y, v;
x = read(); y = read(); v = read();
addedge(x, y, v);
}
printf("%d
", sap(s, t));
return 0;
}
增广路算法求最大流
模板LG P3376
DFS太慢,EK算法其实也很慢....(既然是NOIP选手不掌握fastest也没问题吧)
#include<bits/stdc++.h>
using namespace std;
const int oo = 0x7f7f7f7f;
const int N = 10010;
template <typename T>
T read(){
T n(0), f(1);
char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
for(; isdigit(ch); ch = getchar()) n = n*10 + ch-48;
return n*f;
}
struct Edge{
int u, v, cap, flow;
Edge(int from, int to, int c, int f):u(from), v(to), cap(c), flow(f){}
};
int n, m;
int a[N], p[N];
vector<Edge> edges;
vector<int> G[N];
#define pb push_back
void init(){
for(int i = 1; i <= n; ++i) G[i].clear();
edges.clear();
}
void addedge(int u, int v, int cap){
edges.pb(Edge(u, v, cap, 0));
edges.pb(Edge(v, u, 0, 0));
int tm = edges.size();
G[u].pb(tm-2);
G[v].pb(tm-1);
}
int EK(int s, int t){
int flow = 0;
for(;;){
memset(a, 0, sizeof(a));
queue<int> Q;
Q.push(s);
a[s] = oo;
while(!Q.empty()){
int x = Q.front(); Q.pop();
for(int i = 0; i < G[x].size(); ++i){
Edge& e = edges[G[x][i]];
if(!a[e.v] && e.cap > e.flow){
p[e.v] = G[x][i];
a[e.v] = min(a[x], e.cap-e.flow);
Q.push(e.v);
}
}
if(a[t]) break;
}
if(!a[t]) break;
for(int i = t; i != s; i = edges[p[i]].u){
edges[p[i]].flow += a[t];
edges[p[i]^1].flow -= a[t];
}
flow += a[t];
}
return flow;
}
int main(){
int s, t;
n = read<int>(); m = read<int>();
s = read<int>(); t = read<int>();
init();
for(int i = 1; i <= m; ++i){
int u, v, w;
u = read<int>();
v = read<int>();
w = read<int>();
addedge(u, v, w);
}
printf("%d
", EK(s, t));
return 0;
}
最小费用最大流
模板LG P3381
用Bellmanford求
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 5010;
const int M = 50010;
const int oo = 0x7f7f7f7f;
template <typename T>
T read(){
T n(0), f(1);
char ch = getchar();
for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
for(; isdigit(ch); ch = getchar()) n = n*10 + ch-48;
return n*f;
}
#define read() read<int>()
struct Edge{
int from, to, cap, flow, cost;
Edge(int u, int v, int c, int f, int val):from(u), to(v), cap(c), flow(f), cost(val){}
};
int n, m;
vector<Edge> edges;
vector<int> G[N];
int a[N], d[N], p[N], inq[N];
#define pb push_back
void addedge(int x, int y, int w, int v){
edges.pb(Edge(x, y, w, 0, v));
edges.pb(Edge(y, x, 0, 0, -v));
int tm = edges.size();
G[x].pb(tm-2);
G[y].pb(tm-1);
}
void init(){
for(int i = 1; i <= n; ++i) G[i].clear();
edges.clear();
}
bool BMFD(int s, int t, int& flow, ll& cost){
memset(inq, 0, sizeof(inq));
for(int i = 1; i <= n; ++i) d[i] = oo;
d[s] = p[s] = 0; a[s] = oo; inq[s] = 1;
queue<int> Q;
Q.push(s);
while(!Q.empty()){
int u = Q.front(); Q.pop();
inq[u] = 0;
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;
a[e.to] = min(a[u], e.cap-e.flow);
p[e.to] = G[u][i];
if(!inq[e.to]){ Q.push(e.to); inq[e.to] = 1; }
}
}
}
if(d[t] == oo) return false;
flow += a[t];
cost += 1ll*d[t]*a[t];
for(int i = t; i != s; i = edges[p[i]].from){
edges[p[i]].flow += a[t];
edges[p[i]^1].flow -= a[t];
}
return true;
}
int MCMF(int s, int t, ll& cost){
int flow = 0; cost = 0;
while(BMFD(s, t, flow, cost));
return flow;
}
int main(){
int s, t;
n = read(); m = read();
s = read(); t = read();
init();
for(int i = 1; i <= m; ++i){
int x, y, w, v;
x = read(); y = read();
w = read(); v = read();
addedge(x, y, w, v);
}
ll cost = 0;
printf("%d ", MCMF(s, t, cost));
printf("%lld
", cost);
return 0;
}