一、最小費用最大流的模型
在保證流量最大的前提下,所需的費用最小,這就是最小費用最大流問題.
帶有費用的網路流圖: g=(v,e,c,w)
v:頂點; e:弧;c:弧的容量;w:單位流量費用。
任意的弧對應非負的容量c[i,j]和單位流量費用w[i,j]。滿足:
① 流量f是g的最大流。
② 在f是g的最大流的前提下,流的費用最小。
f是g的最大流的集合(最大流不止乙個):
在最大流中尋找乙個費用最小的流 f.
二、最小費用最大流的演算法
基本思路:
把弧的單位費用w[i,j]看作弧的路徑長度,每次找從源點s到匯點t長度最短(費用最小)的可增廣路徑進行增廣。
1. 最小費用可增廣路
2. 路徑s到t的長度即單位流量的費用。
ps:是網路流ek演算法的改進,在求增廣路徑的時候,把bfs改為帶權的spfa,每次求權值最小的增廣路。
ps:要注意一點,逆邊cost[i][j] = -cost[j][i],不能忘了加上去。
//鄰接矩陣。
#include#include#includeusing namespace std;
#define max 310
#define inf 0x3f3f3f3f
int n, ans,en,st;
int cap[max][max], pre[max];
int cost[max][max], dis[max];
int que[max];
bool vis[max];
bool spfa()
dis[st] = 0;
que[0] = st;
vis[st] = true;
while(tail != head)
}vis[u] = false;
head ++;
if(head == max) head = 0;
}if(dis[en] == inf) return false;
return true;}
void end()edge[emax];
int n, m, ans;
int k, edgehead[nmax];
int que[nmax], pre[nmax], dis[nmax];
bool vis[nmax];
void addedge(int u, int v, int ca, int co)
bool spfa()
dis[0] = 0;
que[0] = 0;
vis[u] = true;
while(tail > head)}}
vis[u] = false;
}if(dis[n] == inf) return false;
return true;}
void end()
for(u = n; u != 0; u = edge[edge[p].re].v)}
int main()
最小費用最大流模板
const int n 1010 點 const int m 2 10010 邊 const int inf 1000000000 struct nodee m int next1 m point n dis n q n pre n ne ne為已新增的邊數,next,point為鄰接表,dis為花...
最小費用最大流 模板
因為含有負權邊,所以使用spfa進行增廣。指定流量的最小費用流可以初始化乙個f,然後每次一直迴圈到f 0為止。函式返回的是最大流,當然經過少量修改可以返回最小費用,利用最小流量乘以相應的費用即可。prevv記錄父節點,preve記錄當前節點對應父節點的第幾條邊。const int inf 0x3ff...
最大流最小費用(模板)
在最大流上加了乙個費用 用ek的方法先用spfa找最小費用的乙個可行流,在一次次修改,與最大流思想一樣,不過找最短路時需要建乙個負邊 include include include include using namespace std const int m 199999 int n,m,s,t ...