羅区P2604 +最大流最小コストの最大流量

トピックへのリンク: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、00 );
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      追加(01、K、0); // 新しいソース0を追加し、容量拡張がk、0コストを必要とします。だから、Kでなければならないフルフローを実行します。
108      追加(1000 );
109      MCMF(0 、N);
110      のprintf(" %d個の\ n " 、min_cost)。
111      戻り 0 ;
112 }
コードの表示

 

おすすめ

転載: www.cnblogs.com/yuanweidao/p/11275982.html