您的位置:首页 > 其它

最小费用最大流模板

2016-03-14 12:48 429 查看
#include <bits/stdc++.h>

using namespace std;
const int inf = 0x3f3f3f3f;
const int maxn = 350;

struct Edge { int from, to, cap, flow, cost; };
vector<Edge> edges;
vector<int> G[maxn];
int inque[maxn];   //spfa
int d[maxn];    //源点到当前点的最短路
int p[maxn];    //入弧编号
int a[maxn];    //可改进量

void init(int 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});
int m = edges.size();
G[from].push_back(m-2);
G[to].push_back(m-1);
}

bool spfa(int s, int t, int &flow, long long &cost)
{
memset(d, 0x3f, sizeof(d));
memset(inque, 0, sizeof(inque));
d[s] = 0; inque[s] = 1;
a[s] = inf; p[s] = 0;
queue<int> que;
que.push(s);
while(!que.empty()){
int u = que.front(); que.pop();
inque[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;
if(!inque[e.to]) que.push(e.to), inque[e.to]=1;
p[e.to] = G[u][i];   //e.to的入弧编号
a[e.to] = min(a[u], e.cap-e.flow);   //更新可改进量
}
}
}
if(d[t] == inf) return false;
flow += a[t];
cost += (long long)a[t]*(long long)d[t];
for(int u=t; u!=s; u=edges[p[u]].from){
edges[p[u]].flow += a[t];
edges[p[u]^1].flow -= a[t];
}
return true;
}

int MCMF(int s, int t, long long &cost)
{
int flow = 0; cost = 0;
while(spfa(s, t, flow, cost));
return flow;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: