#include "iostream"
#include "stack"
#include "vector"
#include "string.h"
#define min(a, b) a < b ? a : b
using namespace std;
struct Edge
{
int to; //终点
int cap; //容量
int cost; //花费
int rev; //反向边的编号
};
const int INF = 100000;
const int MAX_V = 100;
int V; //顶点数
vector<Edge> G[MAX_V];
int dist[MAX_V]; //最短距离
int prev[MAX_V]; //最短路中前驱结点对应的点
int pree[MAX_V]; //最短路中前驱结点对应的边
void addEdge(int from, int to, int cap, int cost)
{
Edge e;
e.to = to;
e.cap = cap;
e.cost = cost;
e.rev = G[to].size();
G[from].push_back(e);
Edge re;
re.to = from;
re.cap = 0;
re.cost = -cost;
re.rev = G[from].size() - 1;
G[to].push_back(re);
}
//求从s到t,流量为f的最小费用流
//如不能增广,返回-1
int min_cost_flow(int s, int t, int f)
{
int res = 0; //最小花费
while(f > 0)
{
fill(dist, dist+V, INF);
dist[s] = 0;
bool update = true;
while(update)
{
update = false;
for(int i=0; i<V; i++)
{
if(dist[i] == INF)
continue;
for(int j=0; j<G[i].size(); j++)
{
Edge &e = G[i][j];
if(dist[e.to] > dist[i] + e.cost && e.cap > 0)
{
dist[e.to] = dist[i] + e.cost;
prev[e.to] = i;
pree[e.to] = j;
update = true;
}
}
}
}
//不能再增广
if(dist[t] == INF)
return -1;
//沿着s到t的最短路尽量增广
int d = f;
int v;
for(v=t; v!=s; v=prev[v])
{
d = min(d, G[prev[v]][pree[v]].cap);
}
f -= d;
res += d * dist[t];
for(v=t; v!=s; v=prev[v])
{
Edge &e = G[prev[v]][pree[v]];
e.cap -= d;
G[v][e.rev].cap += d;
}
}
return res;
}
int main()
{
V = 5;
addEdge(0, 1, 10, 2);
addEdge(0, 2, 2, 4);
addEdge(1, 2, 6, 6);
addEdge(1, 3, 6, 2);
addEdge(2, 4, 5, 2);
addEdge(3, 2, 3, 3);
addEdge(3, 4, 8, 6);
cout << "流量为9时的最小花费为:" << min_cost_flow(0, 4, 9) << endl;
return 0;
}
最小费用流
最新推荐文章于 2023-03-08 00:16:04 发布