解決
コストの流れを考えるのは簡単
問題に右の点を解決するためには、障害物のない私は2つのポイントに分けポイントは、双方向の愛
AIから側(これらの非生産的で表現)0のコストで正の無限大(示さ無制限パス)のBIも流れに
(を通じて一度だけ示される)1の点は、I石であれば、再びAIからBIにも流量1の費用で(これは1を通じて収益を表す)エッジ
ポイントは、私がjを指すことができますし、i、jは、BI AJからも、正の無限大の流れ、ゼロコストの側に、障害物でない場合
A1は0エッジのコストで車両の数を検出するためにも開始点から流出します
BNからも0エッジのコストでプローブ車両の数とトラフィックの終わりまで
最大のコストの最大フローを実行します
コード
書式#include <cstdioを> する#include <cstdlib> 書式#include <キュー> の#include <CStringの> の#include <アルゴリズム> 使用して 名前空間をSTD。 CONST INT N = 3E3、M = 1E5。 int型のプレ[N]、S、T、車、D [N]、N、M、INCF [N]、[ 40 ] [ 40 ]、INF = 1 << 30 、DIS [N]。 INTヘッド[N]、NXT [M]、版[M]、エッジ[M]、コスト[M]、TOT = 1 、maxflow、maxcost。 BOOL で[N]。 INTの ID(int型のx、int型のy、int型INV) { 戻り(X- 1)* M + Y + INV * N * M。 } ボイド追加(INT U、INT V、INT、W INT C) { 版[ ++ TOT = V、NXT [TOT =頭部[U]、エッジ[TOT =コスト[TOT = C、W、ヘッド[U] = TOT。 版【 ++ TOT = U、NXT [TOT =頭部[V]、エッジ[TOT = 0、コスト[TOT] = - C、頭[V] = TOT。 } ブールspfa() { memsetの(DIS、0x80を、はsizeof (DIS))。 memsetの(前、0、はsizeof (PRE))。 int型最後= DIS [S]。 キュー < 整数 > Q; DIS [S] = 0、q.push(S)、INCF [S] = 1 << 30 。 しばらく(!q.empty()) { int型のu = q.front(); q.pop(); で [U] = 偽。 以下のために(INT iがヘッド[U]、Vが=; I;私は= NXT [I])の 場合(エッジ[I]> 0 && DIS [V =版[I] <DIS [U] + コスト[i])と { DIS [V] = DIS [U] + コスト[i]は、 INCF [V] =分(エッジ[I]、INCF [U])。 事前[V] = I。 もし(!で [V])で [V] = 真、q.push(V); } } を返す DIS [t]を=!最後。 } ボイド更新() { maxflow + = INCF [T]、maxcost + = INCF [T] * DIS [T]。 int型のx = T; 一方、(!X = S) { int型 I = プレ[X]。 エッジ[I] - = INCF [T]、エッジ[I ^ 1 ] + = INCF [T]。 X =版[I ^ 1 ]。 } } ボイド DFS(int型のx、int型のy、int型の POS、INT K) { int型KX、KY、MOV。 以下のために(INT iが[POS]ヘッド=; I;私は= NXT [I]) { int型 V = 版[I]を、 もし(V == S || V == T || V == POS-N * M ||エッジ[I ^ 1 ] <= 0)続けます。 エッジ[I ^ 1 ] - 。 もし(V> N * M) { DFS(X、Y、V、K)。 リターン; } もし(V ==(X- 1)* M + Y + 1)KX = X、KY = Y + 1、MOV = 1 。 他 KX = X + 1、KY = Y、MOV = 0 。 printf(" %D%D \ n " 、K、MOV)。 DFS(KX、KY、V + N * M、K)。 リターン; } } int型のmain() { scanf関数(" %D%D%D "、&車、&M、&N) S = 0、T = N * M * 2 + 1 。 以下のための(int型 I = 1 ; I <= N; I ++ ) のための(INT J = 1 ; J <= Mであり、j ++ ) のscanf(" %dの"、および[I] [J])。 もし([n]は[M] == 1 || [ 1 ] [ 1 ] == 1)戻り 0 ; 以下のために(INT iが= 1 ; iが<= N; I ++ ) のための(INT J = 1 ; J <= Mであり、j ++ ) { 場合([I] [J] == 1)続行します; 追加(ID(I、J、0)、ID(I、J、1)、INF、0 ); もし([I] [J] == 2)を追加(ID(I、J、0)、ID(I、J、1)、1、1 )。 もし(I <N && [I + 1 ] [J] =!1)(ID(I、J、追加1)、ID(I + 1、J、0)、INF、0 ); もし(J <M && [I]、[J + 1 ]!= 1)を追加(ID(I、J、1)、ID(I、J + 1、0)、INF、0); } 、(S、ID(追加1、1、0)、車、0)、追加(ID(N、M、1)、T、車、0 ); 一方、(spfa())更新(); 以下のために(INT iが= 1 ; I <= maxflow I ++ ) DFS(1、1、1 、I)。 リターン 0 ; }