トピックへのリンク:https://www.luogu.org/problem/P2604
タイトル説明
有向グラフ与えられ、各エッジは、容量Cを有し、膨張はW.コスト ここでは、拡張コストは1の容量を拡張するために必要なコストを参照してください。要件:1、拡大せずに、Nの最大流量に、図2に示すように、膨張はN、最大流量にK 1の最小コストを増加させるであろう。
問題解決のアイデア:
1. 1の場合、最大流量は、直接ゼロに、再度コストを実行することができます。
2. 2の場合、ネットワーク内の各辺プラスINF容量、コスト側膨張コストを境最大残差ストリームをカバーします。これは、コストも1:00に、K、0の膨張プラス源、K、0コストの容量を確保するために、正しいことを保証します。最小コストを実行し(0、N)とすることができます。
3.交通費よりも単価が、展開のコストのエッジので、あなたは残りのネットワーク上で接しできる理由を考えてみてください。何の拡張がないため、ストリームの他の側面の下でトラフィックのフローを増加する側の完全な拡張を持っているために、もう一方の側のコストは、ゼロです。他方の側はまた、完全な流れになった後、それは拡張費用を必要とするだけでなく、残留ネットワークので(INFの追加エッジを使用します
コストは、それが使用する優先順位を与えるだろう、ゼロです)
コード:
1の#include <stdio.hの> 2の#include < 文字列・H> 3の#include <キュー> 4の#include <アルゴリズム> 5 の#define MEM(A、B)のmemset(A、B、はsizeof(A)) 。6 使用 名前空間STD; 7 のconst int型 MAXM = 5010 ; 8 のconst int型 = MAXN 5000 ; 9 のconst int型 INF = 0x3f3f3f3f ; 10 。11 int型 N-、M、K; // n点、mはエッジを有する、膨張K 12である <キューINT> Q; 13 INTのDEP [MAXN]、最後[MAXN]、プリ[MAXN]、DIS [MAXN]、流動[MAXN]、VIS [MAXN]。 14 15 構造体ノード 16 { 17 int型A、B、C、D。 18 } NO [MAXM]。 19 int型のTOT; 20 21 構造体のエッジ 22 { 23 INT 、隣、流れ、DIS。 24 }エッジ[ 5 * MAXN]。 25 int型ヘッド[MAXN]、CNT。 26 27 ボイドアドオン(int型、int型、B、int型 C、int型D) 28 { 29 エッジ[++ CNT] .TO = B。 30 エッジ[CNT] .next = ヘッド[A]。 31 エッジ[CNT] .flow = C。 32 エッジ【CNTは] = .DIS D。 33 頭[A] = CNT。 34 } 35 36 int型 spfa(INT ST、int型ED) 37 { 38 ながら(!Q.empty()) 39 Q.pop()。 40 MEM(VIS、0)、MEM(流量、INF)、MEM(DIS、INF)、プリ[ED] = - 1 。 41の DIS [ST] = 0 ; 42 VIS [ST] = 1 。 43 Q.push(ST)。 44 ながら(!Q.empty()) 45 { 46 INT今= Q.front()。 47 Q.pop()。 48 VIS [今] = 0 ; 49 のために(int型 I =ヘッド[今]; I =! - 1 ; I = エッジ[I] .next) 50 { 51 INT =のエッジ[I] .TO。 52 であれば(エッジ[I] .flow> 0 && DIS [に対する]> DIS [今] + エッジ[I] .DIS) 53 { 54の = DIS [今] + [へ] DIS エッジ[I] .DIS。 55 [へ]最後= I。 56 プレ[に対する] = 今。 57 = [へ]流分([今]エッジを流れる[I] .flow)。 58 であれば(!VIS [に対して]) 59 { 60 VIS =〔へ] 1 。 61 Q.push(へ)。 62 } 63 } 64 } 65 } 66 リターンプレ[ED] =! - 1 。 67 } 68 69 int型min_cost、max_flow。 70 ボイド MCMF(int型 ST、int型編) 71 { 72 min_cost = 0 。 73 max_flow = 0 。 74 一方(spfa(ST編)) 75 { 76 INT今= ED。 77 min_cost + =流量[ED] * DIS [ED]。 78 max_flow + = 流量[ED]。 79 ながら(!今= ST) 80 { 81 エッジ[最後[今]フロー- = [ED]を流れます。 82 エッジ[最後[今] ^ 1 ] .flow + = 流[ED]。 83 今= 事前[今]。 84 } 85 } 86 } 87 88 のint main()の 89 { 90 のscanf(" %D%D%D "、&N、&M、およびK); 91 MEM(ヘッド、 - 1)、CNT = - 1、TOT = 0 。 92 のために(int型 I = 1 ; I <= M Iは++ ) 93 { 94 int型A、B、C、D。 95 のscanf(" %D%D%D%D "、&A、&B、&C&D)。 96ない NO [I] .Aは、NO [i]は.B = B、NO [I] .C = C、NO [I] .D = D =をしません。 // 把输入的边记录下来 97 追加(A、B、C、0 ); 98 追加(B、0、0 ); 99 } 100 MCMF(1、N-); 101 のprintf(" %のD " 、max_flow); 102 のために(INT I = 1 ; I <= M、Iが++)// ネットワークプラスコラージュコストINFの残容量Dで 103 { 104 追加(NO [I] II.A、NO [I] .B、INF、NO [I] 2.D); 105 追加(NO [I] .B、NO [I] II.A、0、 - NO [I ] 2.D); 106 } 107 追加(0、1、K、0); // 新しいソース0を追加し、容量拡張がk、0コストを必要とします。だから、Kでなければならないフルフローを実行します。 108 追加(1、0、0、0 ); 109 MCMF(0 、N); 110 のprintf(" %d個の\ n " 、min_cost)。 111 戻り 0 ; 112 }