struct Edge {
int v, w, nxt, cost, sy;
}edge[maxn];
char MP[maxn][maxn];
int head[maxn], dis[maxn], vis[maxn], pre[maxn], tot;
int S, T, n, m;
void init() {
tot = 0;
T = n * m + 1;
S = 0;
memset(head, -1, sizeof(head));
}
void addEdge(int u, int v, int w, int cost) {
edge[tot].v = v;
edge[tot].w = w;
edge[tot].sy = 0;
edge[tot].cost = cost;
edge[tot].nxt = head[u];
head[u] = tot ++;
edge[tot].v = u;
edge[tot].w = 0;
edge[tot].sy = 0;
edge[tot].cost = -cost;
edge[tot].nxt = head[v];
head[v] = tot ++;
}
bool SPFA() {
memset(dis, INF, sizeof(dis));
memset(vis, 0, sizeof(vis));
memset(pre, -1, sizeof(pre));
queue<int> que;
que.push(S);
dis[S] = 0;
vis[S] = 1;
pre[S] = -1;
while(!que.empty()) {
int u = que.front(); que.pop();
vis[u] = 0;
for (int i = head[u]; i + 1; i = edge[i].nxt) {
if(dis[edge[i].v] > dis[u] + edge[i].cost && edge[i].w > edge[i].sy) {
dis[edge[i].v] = dis[u] + edge[i].cost;
pre[edge[i].v] = i;
if(!vis[edge[i].v]) {
vis[edge[i].v] = 1;
que.push(edge[i].v);
}
}
}
}
if(pre[T] == -1)
return 0;
return 1;
}
int MinCostMaxFlow(int &Cost) {
int Flow = 0, MinFlow = INF;
Cost = 0;
while(SPFA()) {
for (int i = pre[T]; i + 1; i = pre[edge[i ^ 1].v])
MinFlow = min(MinFlow, edge[i].w - edge[i].sy);//最小流量
for (int i = pre[T]; i + 1; i = pre[edge[i ^ 1].v]) {
edge[i].sy += MinFlow;
edge[i ^ 1].sy -= MinFlow;
Cost += edge[i].cost * MinFlow;//费用= sigma每条路线的最小流量*花费
}
Flow += MinFlow;
}
return Flow;//返回最大流
}
int ans = 0;
MinCostMaxFlow(ans);
这是一般的最大流最小费的模版,
如果是最大费最小流的话,把w与cost的位置互换,
如果是最大流最大费的话,把cost的值存负,用最大流最小费的方法求,最后取反即可