- 最小费用最大流
- 最大费用最小流,建边的时候,把花费和流量调换位置
- 最大费用最大流,建边的时候,把正向的费用存为负值,结果取负号
spfa模板
int path[maxn], dis[maxn], head[maxn], vis[maxn], cnt;
void init() {
cnt = 0;
memset(head, -1, sizeof(head));
}
struct ac{
int v, c, cost, nex;
}edge[maxn << ];
void addedge(int u, int v, int c, int cost) {
edge[cnt] = {v, c, cost, head[u]};
head[u] = cnt++;
edge[cnt] = {u, 0, -cost, head[v]};
head[v] = cnt++;
}
int spfa(int s, int e) {
memset(vis, 0, sizeof(vis));
memset(dis, inf, sizeof(dis));
memset(path, -1, sizeof(path));
queue<int> que;
que.push(s);
dis[s] = 0;
vis[s] = 1;
while (!que.empty()) {
int u = que.front();
que.pop();
vis[u] = 0;
for (int i = head[u]; i != -1; i = edge[i].nex) {
int v = edge[i].v;
int c = edge[i].c;
int cost = edge[i].cost;
if (dis[v] > dis[u] + cost && c > 0) {
dis[v] = dis[u] + cost;
path[v] = i;
if (vis[v]) continue;
vis[v] = 1;
que.push(v);
}
}
}
return dis[e] != inf;
}
int MincostMaxflow(int s, int e, int &cost) {
int maxflow = 0;
while (spfa(s, e)) {
int flow = inf;
for (int i = path[e]; i != -1; i = path[edge[i^1].v]) {
flow = min(flow, edge[i].c);
}
for (int i = path[e]; i != -1; i = path[edge[i^1].v]) {
edge[i].c -= flow;
edge[i^1].c += flow;
cost += flow * edge[i].cost;
}
maxflow += flow;
}
return maxflow;
}
D i j k s t r a + 链 式 Dijkstra + 链式 Dijkstra+链式
int preE[maxn], preV[maxn], dis[maxn], head[maxn], vis[maxn], h[maxn], cnt;
void init() {
cnt = 0;
memset(head, -1, sizeof(head));
}
struct ac{
int v, c, cost, nex;
}edge[maxn << 8];
void addedge(int u, int v, int c, int cost) {
edge[cnt] = {v, c, cost, head[u]};
head[u] = cnt++;
edge[cnt] = {u, 0, -cost, head[v]};
head[v] = cnt++;
}
int Dijkstra(int s, int e) {
memset(dis, inf, sizeof(dis));
preE[s] = -1, dis[s] = 0;
priority_queue< pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>> >que;
que.push(pair<int,int>(0, s));
while (!que.empty()) {
pair<int, int> top = que.top();
que.pop();
int u = top.second;
if (dis[u] < top.first) continue;
for (int i = head[u]; i != -1; i = edge[i].nex) {
int v = edge[i].v;
int cost = edge[i].cost;
int c = edge[i].c;
if (c > 0 && dis[v] > dis[u] + cost + h[u] - h[v]) {
dis[v] = dis[u] + cost + h[u] - h[v];
preE[v] = i;
preV[v] = u;
que.push(pair<int,int>(dis[v], v));
}
}
}
return dis[e] != inf;
}
int MincostMaxflow(int s, int e, int &cost) {
int maxflow = 0;
memset(h, 0, sizeof(h));
while (Dijkstra(s, e)) {
for (int i = 0; i <= e; ++i) h[i] += dis[i];
int flow = inf;
for (int i = e; i != s; i = preV[i]) {
flow = min(flow, edge[preE[i]].c);
}
for (int i = e; i != s; i = preV[i]) {
edge[preE[i]].c -= flow;
edge[preE[i]^1].c += flow;
}
cost += flow * h[e];
maxflow += flow;
}
return maxflow;
}
D i j k s t r a + V e c t o r Dijkstra + Vector Dijkstra+Vector
int preE[maxn], preV[maxn], dis[maxn], h[maxn];
struct ac{
int v, c, cost, nex;
};
vector<ac> g[maxn];
void init() {
for (int i = 0; i < maxn; ++i) g[i].clear();
}
void addedge(int u, int v, int c, int cost) {
g[u].push_back({v, c, cost, (int)g[v].size()});
g[v].push_back({u, 0, -cost, (int)g[u].size()-1});
}
int Dijkstra(int s, int e) {
priority_queue< pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>> >que;
que.push(pair<int,int>(0, s));
memset(dis, inf, sizeof(dis));
dis[s] = 0;
while (!que.empty()) {
pair<int, int> top = que.top();
que.pop();
int u = top.second;
if (dis[u] < top.first) continue;
for (int i = 0; i < (int)g[u].size(); ++i) {
int v = g[u][i].v;
int cost = g[u][i].cost;
int c = g[u][i].c;
if (c > 0 && dis[v] > dis[u] + cost + h[u] - h[v]) {
dis[v] = dis[u] + cost + h[u] - h[v];
preE[v] = i;
preV[v] = u;
que.push(pair<int,int>(dis[v], v));
}
}
}
return dis[e] != inf;
}