來糊一篇部落格……順便可以記記模板啥的……
廢話不多說直接進入正題……
前置芝士:spf
aspfa
spfa
核心思想算是貪心吧……
每次跑一遍spf
aspfa
spfa
,以邊的費用跑一遍最短路,這樣可以確保找到一條費用最小的路徑,然後在跑的過程中計算出流量並記錄路徑,然後把路徑上的邊的流量都減掉就行了
模板如下(使用鏈式前向星存圖)
變數解釋:dis
disdi
s為最短距離,f
ff為最大流,frfr
fr為路徑,flo
wflow
flow
為邊費用,w
ww為邊流量
bool
spfa()
//以費用為長度跑最短路}}
}return dis[t]
!=inf;
}void
modifyflow()
//跑完之後處理路徑
ans+
=f[t]
*dis[t];}
void
mcmf()
前置芝士:spf
aspfa
spfa
(最好是slf
slfsl
f_spfa
spfa
spfa
),d in
ic
dinic
dinic
個人感覺zkw
zkwzk
w大爺的這個方法和din
ic
dinic
dini
c很相似啊……
先%%%zkw
zkwzk
w大爺然後開始講(瞎)吧(bb)
先從匯點跑spf
aspfa
spfa
,預處理出到每個位置的最短距離(這裡用了slf
slfsl
f優化),然後跑din
ic
dinic
dini
c找增廣路,跑最大流,用最大流乘上距離,一直跑直到滿流即可
(d in
ic
dinic
dini
c還能加弧優化!)
至於為什麼這個方法快……我一時半會兒也想不到……
總之%%%zkw
zkwzk
w大爺肯定沒錯辣
模板如下(使用鏈式前向星存圖,變數命名規則與上方一致)
bool
spfa()
//slf_spfa}}
}return dis[s]
!=inf;
}int
dfs(
int u,
int stream)
//弧優化dinic【偽】}}
return used;
}void
zkwmcmf()
}}
做法有兩種……
最小費用最大流的建圖是這樣:
addedge
(from,to,flow,cost)
;addedge
(to,from,0,
-cost)
;
那我們就採用一種求最長路時會用的技巧,把費用變負,再直接跑即可
建圖如下:
addedge
(from,to,flow,
-cost)
;addedge
(to,from,
0,cost)
;
我們還可以使用另一種求最長路時的技巧,即改變spf
aspfa
spfa
的鬆弛條件
(i nf
infin
f的值也要隨之改變)
e kek
ek的一般寫法:
memset
(dis,60,
sizeof
(dis));
...if
(dis[v]
>dis[u]
+flow[i]
&& w[i]).
..
改變鬆弛條件後:
memset
(dis,-60
,sizeof
(dis));
...if
(dis[v]
+flow[i]
&& w[i]).
..
zkw
zkwzk
w費用流的一般寫法:
memset
(dis,60,
sizeof
(dis));
...if
(dis[v]
>dis[u]
-flow[i]
&& w[i^1]
)...
改變鬆弛條件後:
memset
(dis,-60
,sizeof
(dis));
...if
(dis[v]
-flow[i]
&& w[i^1]
)...
要改變的地方也僅有兩處
歡迎找bug
bugbu
g f in
.fin.
fin.
模板 最小費用最大流 費用流
給出乙個網路圖,以及其源點和匯點,每條邊已知其最大流量和單位流量費用,求出其網路最大流和在最大流情況下的最小費用。既然是模板題,那麼資料肯定很水。我ek spf aek spfa 都過了。費用流其實就是最大流改乙個spf aspf a而已,很簡單。include include include in...
網路流 最小費用最大流
q 為什麼突然想搞網路流?a 迫於tham 蛤mu的淫威 用最短路演算法求出s t的路徑 把路徑要摳出來,而且每條邊要有容量 算一下路徑裡面的可以流過的最大的流量 發現此時的花費就是 dis t flow 累加即可.重複1 3直到不能夠到達t.include include include incl...
最小費用最大流
網 絡流的基本問題為 設乙個有向賦權圖g v,e v 其中有兩個特殊的節點s和s s稱為發點,s 稱為收點。圖中各 邊的方向和權數表示允許的流向和最大可能的流量 容量 問在這個網路圖中從發點流出到收點匯集,最大可通過的實際流量為多少?流向的分布情況為怎樣?設有乙個網路圖g v,e v e中的每條邊 ...