1つの#include <ビット/ STDC ++ H> 2 使用して 名前空間STDを、 3 のconst int型 MAXN = 205、INF = 0x3f3f3f3f 。 4 構造体のエッジ{ 5 INT から、キャップに、フロー、コスト。 6 }。 7 構造体MCMF { 8 int型N、M、S、T。 9 ベクトル<エッジ> エッジ。 10 ベクター< INT > G [MAXN]。 11 INT [MAXN] INQ。 12 int型D [MAXN]。 13 int型のp [MAXN]。 14 INT [MAXN]。 15 16 ボイドのinit(int型N){ 17 本 - > N = N。 18 のためには、(int型、I = 1 ; ++; iが<= N I)G [i]が.clear(); 19 edges.clear()。 20 } 21 22 空隙 AddEdge(INT から、INTに、int型のキャップ、int型の{コスト) 23 edges.push_back((エッジ){ から、に、キャップ、0、コスト})。 24 edges.push_back((エッジ){に、から、0、0、 - コスト})。 25 、M = edges.size()。 26 G【から】.push_back(M- 2 )。 27 .push_back【に】G(M- 1 )。 28 } 29 BOOL BellmanFord(INT S、INT T、INT&流れ、INT&コスト){ 30 のためには、(int型 i = 1 ; iが<= N; ++ I)D [i]は=infファイル。 31 のmemset(INQ、0、はsizeof (INQ))。 32 D [S] = 0 ; INQ [S] = 1。P [S] = 0 ; [S] = INF。 33 34 キュー< 整数 > QUE。 35 que.push(S); 36 ながら(!que.empty()){ 37 INT U = que.front()。que.pop(); 38 INQ [U] = 0 。 39 のためには、(int型、I = 0 ; iが[U] .size()Gを<; ++I){ 40 エッジ&E = 縁[G [U] [I]]。 41 であれば(e.cap> e.flow && D [e.to]> D [U] + e.cost){ 42 D [e.to] = D [U] + e.cost。 43 P [e.to] = G [U] [I]。 44 [e.to] =分([U]、e.cap- e.flow)。 45 もし {que.push(e.to)(INQ [e.to]!)。INQ [e.to] = 1 。} 46 } 47 } 48 } 49 場合(D [T] == INF)を返し 偽。 50 フロー+ = [T]。 51 費用+ = D [T] * [T]。 52 INT U = T。 53 ながら(!U = S){ 54の 。エッジ[P [U]フローは+ = [T]。 55の エッジ[P [U] ^ 1 ] .flowは- = [t]を。 56 U =エッジ[P [U]。から; 57 } 58 リターン 真。 59 } 60 INT mincost(INT S、INT T){ 61 int型フロー=0、コスト= 0 。 62 一方(BellmanFord(S、T、流量、コスト))。 63 リターン・コスト; 64 } 65 } MCMF。 66 INT [MAXN]、B [MAXN]、C [MAXN] [MAXN]。 67 INT メイン(){ 68 int型 M、N。scanf関数(" %d個の%のD "、&M、&N) 69 INT S = M + N + 1、T = M + N + 2 。 70 71 のために(int型 I = 1 ; I <= M; ++ I)のscanf(" %dの"、&[I])。 72 のために(INT J = 1 ; J <= N; ++ j)はscanf関数(" %のD "、&B [J])。 73 のためには、(int型 I = 1 ; I <= M; ++ I){ 74 のための(int型 J = 1 ; J <= N; ++ j)は{ 75 のscanf(" %dの"、&C [i]は[ J]); 76 } 77 } 78 // 最小费用最大流 79 mcmf.init(N + M + 2 )。 80 のためには、(int型 I = 1 ; I <= M; ++ I){ 81 mcmf.AddEdge(S、I、[I]、0 ); 82 } 83 のための(int型 I = 1 ; I <= M; ++ I){ 84 のための(int型 J = 1 ; J <= N; ++ j)は{ 85 mcmf.AddEdge(I、J + M、INF、 C [I] [J])。 86 } 87 } 88 のために(INT J = 1 ; J <= N; ++ j)は{ 89 mcmf.AddEdge(J + M、T、B [j]が、0 ); 90 } 91 のprintf(" %d個の\ n " 、mcmf.mincost(S、T))。 92 93 // 最大费用最大流 94 mcmf.init(N + M + 2 )。 95 のためには、(int型 I = 1 ; I <= M; ++ I){ 96 mcmf.AddEdge(S、I、[I]、0 ); 97 } 98 のための(int型 I = 1 ; I <= M; ++ i)が{ 99 のために(INT J =1 ; J <= N。++ J){ 100 mcmf.AddEdge(I、J + M、INF、 - C [I] [J])。 101 } 102 } 103 用(INT J = 1 ; J <= N; ++ j)は{ 104 mcmf.AddEdge(J + M、T、B [j]が、0 ); 105 } 106 のprintf(" %d個の\ n "、 - mcmf.mincost(S、T))。 107 リターン 0 ; 108 }