/**
一個多月沒碰,感覺忘完了……
最小費就是有多條路可以滿足最大流量的情況下所需要的最小費用
把費用改成相反數或改下spfa()的鬆弛就可最大費了
比如:從北京到上海運送一批貨物,給出中間經過每條路線上對每輛車的收費,以及
每條路一次允許經過的車的數量,求一次性從北京到上海送儘可能多的貨物情況下的最
小費用,當然中間經過的路線用二維數組即可表示,還有每條路的費用
則s 爲北京, t 爲上海, 帶下面的模板即可
把問題轉換成這個模型纔是解決問題的關鍵,模板誰都會噢
*/
int cap[Max][Max], pre[Max], cost[Max][Max];
int que[Max], vis[Max], ans;
bool spfa(int s, int t) {
int i, head = 0, tail = 1;
for (i=0; i<=n; i++) {
dis[i] = inf;
vis[i] = false;
}
dis[s] = 0;
que[0] = s;
while (tail != head) {
int u = que[head++];
vis[u] = true;
for (i=0; i<=n; i++) { //n+1爲點的個數
if (cap[u][i] && dis[i] > dis[u] + cost[u][i]) { //每次挑最小費用的路徑
//這變成 < 即爲最大費
dis[i] = dis[u] + cost[u][i];
pre[i] = u; //記錄增廣路徑
if (!vis[i]) {
vis[i] = true;
que[tail++] = i;
if (tail == max)
tail = 0;
}
}
}
vis[u] = false;
if (head == Max)
head = 0;
}
if (dis[t] < inf)
return true;
return false;
}
void end(int s, int t) {
int i, sum = inf;
for (i=t; i!=s; i=pre[i])
sum = min(sum, cap[pre[i]][i]);
for (i=t; i!=s; i=pre[i]) {
cap[pre[i]][i] -= sum;
cap[i][pre[i]] += sum;
ans += cost[pre[i]][i]*sum;
}
}
int main()
{
//cap爲源點匯點對應邊得流量, cost 兩邊間的費用
//cost賦值 與源點匯點連接的cost 賦爲0, cost[i][j] = a; cost[j][i] = -a;
//設源點爲 s 匯點爲 t
//調用:
ans = 0;
while (spfa(s, t))
end(s, t);
return 0;
}
收藏於 2012-01-08
來自於百度空間
最小費用最大流 spfa() + ek()
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.