模板 - 最小费用最大流
SPFA版本:
#include<bits/stdc++.h>
using namespace std;
namespace SPFA_Mincost_Maxflow {
const int MAXN=10000;
const int MAXM=100000;
const int INF=0x3f3f3f3f;
struct Edge {
int to,next,cap,flow,cost;
} edge[MAXM];
int head[MAXN],tol;
int pre[MAXN],dis[MAXN];
bool vis[MAXN];
void init() {
tol=0;
memset(head,-1,sizeof(head));
}
void add_edge(int u,int v,int cap,int cost) {
edge[tol].to=v;
edge[tol].cap=cap;
edge[tol].cost=cost;
edge[tol].flow=0;
edge[tol].next=head[u];
head[u]=tol++;
edge[tol].to=u;
edge[tol].cap=0;
edge[tol].cost=-cost;
edge[tol].flow=0;
edge[tol].next=head[v];
head[v]=tol++;
}
bool spfa(int s,int t) {
queue<int> q;
memset(dis,INF,sizeof(dis));
memset(vis,false,sizeof(vis));
memset(pre,-1,sizeof(pre));
dis[s]=0;
vis[s]=true;
q.push(s);
while(!q.empty()) {
int u=q.front();
q.pop();
vis[u]=false;
for(int i=head[u]; i!=-1; i=edge[i].next) {
int v=edge[i].to;
if(edge[i].cap>edge[i].flow&&dis[v]>dis[u]+edge[i].cost) {
dis[v]=dis[u]+edge[i].cost;
pre[v]=i;
if(!vis[v]) {
vis[v]=true;
q.push(v);
}
}
}
}
if(pre[t]==-1)
return false;
else
return true;
}
int mincost,maxflow;
void mincost_maxflow(int s,int t) {
int cost=0,flow=0;
while(spfa(s,t)) {
int tp=INF;
for(int i=pre[t]; i!=-1; i=pre[edge[i^1].to]) {
if(tp>edge[i].cap-edge[i].flow)
tp=edge[i].cap-edge[i].flow;
}
for(int i=pre[t]; i!=-1; i=pre[edge[i^1].to]) {
edge[i].flow+=tp;
edge[i^1].flow-=tp;
cost+=edge[i].cost*tp;
}
flow+=tp;
}
mincost=cost;
maxflow=flow;
return;
}
}
using namespace SPFA_Mincost_Maxflow;
int main() {
int N,M,S,T;
scanf("%d%d%d%d",&N,&M,&S,&T);
init();
while(M--) {
int u,v,cap,cost;
scanf("%d%d%d%d",&u,&v,&cap,&cost);
add_edge(u,v,cap,cost);
}
mincost_maxflow(S,T);
printf("%d %d\n",maxflow,mincost);
}
Dijkstra版本:
const int maxn = 5000;
const int INF = 0x3f3f3f3f;
struct Edge {
int to, cap, cost, flow;
Edge() {}
Edge(int to, int _cap, int _cost, int _flow) : to(to), cap(_cap), cost(_cost), flow(_flow) {}
};
struct MinCostMaxFlow {
int V, H[maxn + 5], dis[maxn + 5], prev[maxn + 5], pree[maxn + 5];
vector
//调用前初始化
void init(int n) {
V = n;
for(int i = 0; i <= V; ++i)
G[i].clear();
}
//加边
void addEdge(int from, int to, int cap, int cost) {
G[from].push_back(Edge(to, cap, cost, G[to].size()));
G[to].push_back(Edge(from, 0, -cost, G[from].size() - 1));
}
//flow是自己传进去的变量,就是最后的最大流,返回的是最小费用
int minCostMaxFlow(int s, int t, int f, int& flow) {
int cost = 0;
fill(H, H + 1 + V, 0);
while(f) {
priority_queue <pii, vector
fill(dis, dis + 1 + V, INF);
dis[s] = 0;
q.push(pii(0, s));
while(!q.empty()) {
pii now = q.top();
q.pop();
int v = now.second;
if(dis[v] < now.first)
continue;
for(int i = 0; i < G[v].size(); ++i) {
Edge& e = G[v][i];
if(e.cap > 0 && dis[e.to] > dis[v] + e.cost + H[v] - H[e.to]) {
dis[e.to] = dis[v] + e.cost + H[v] - H[e.to];
prev[e.to] = v;
pree[e.to] = i;
q.push(pii(dis[e.to], e.to));
}
}
}
if(dis[t] == INF)
break;
for(int i = 0; i <= V; ++i)
H[i] += dis[i];
int d = f;
for(int v = t; v != s; v = prev[v])
d = min(d, G[prev[v]][pree[v]].cap);
f -= d, flow += d, cost += d * H[t];
for(int v = t; v != s; v = prev[v]) {
Edge& e = G[prev[v]][pree[v]];
e.cap -= d;
G[v][e.flow].cap += d;
}
}
return cost;
}
} mcmf;
inline int read() {
char ch = getchar();
int x = 0;
while(ch < '0' || ch > '9')
ch = getchar();
while(ch >= '0' && ch <= '9') {
x = (x << 3) + (x << 1) + ch - '0';
ch = getchar();
}
return x;
}
int a[2005];
int main() {
ifdef Yinku
freopen("Yinku.in", "r", stdin);
endif // Yinku
for(int T = read(); T; --T) {
int n = read(), k = read();
int s1 = 0, s2 = 2 * n + 1, t = 2 * n + 2;
mcmf.init(2 * n + 2);
mcmf.addEdge(s1, s2, k, 0);
for(int i = 1; i <= n; ++i) {
a[i] = read();
mcmf.addEdge(i, i + n, 1, -a[i]);
mcmf.addEdge(s2, i, 1, 0);
mcmf.addEdge(i + n, t, 1, 0);
}
for(int i = 1; i <= n; ++i)
for(int j = i + 1; j <= n; ++j)
if(a[j] >= a[i])
mcmf.addEdge(i + n, j, 1, 0);
int flow = 0;
printf("%d\n", -mcmf.minCostMaxFlow(s1, t, INF, flow));
}
}
</details>