実践:直接dinic実行
練習2:双対グラフ最短ターンの最小カットの平面図で、左下の外側領域から出発し、右上端の外側の領域は、2つの領域を接続するエッジは、点のような領域は、最短経路問題となります。
#include <ビット/ STDC ++。H> 名前空間IO { チャー BUF [ 1 << 21 ]、BUF2 [ 1 << 21 ]、[ 20 ]、* P1 = BUF、* P2 = BUF、HH = ' \ n ' 。 int型のp、P3 = - 1 ; ボイドリード(){} ボイドプリント(){} インラインINT GETC(){ リターン P1 == P2 &&(P2 =(P1 = BUF)+関数fread(BUF、1、1 << 21、STDIN)、P1 == P2)?EOF:* P1 ++ ; } インラインボイド{フラッシュを() fwriteの(BUF2、1、P3 + 1、STDOUT)、P3 = - 1 。 } テンプレート <型名T、型名... T2> インラインボイドリード(T&X、T2&... OTH){ T F = 1。X = 0 。 チャー CH = GETC()。 一方、(isdigit(CH)!){ 場合(CH == ' - ')、F = - 1。CH = GETC()。} 一方(isdigit(CH)){X = X * 10 + CH - 48。CH = GETC()。} X * = F。 (OTH ...)読んで。 } テンプレート <型名T、型名... T2> インラインボイドプリント{(Tは、T2 ... OTH X) であれば(P3> 1 << 20 )フラッシュ(); もし(x < 0)BUF2 [++ P3] = 45、X = - X。 やります{ 【 ++ P] = X%10 + 48 。 } 一方、(X / = 10 )。 やります{ BUF2 [ ++ P3] = [P]。 } 一方、( - P)。 BUF2 [ ++ P3] = HH。 印刷(OTH ...)。 } } CONST INT N = 2E6 + 7、M = 6E6 + 7 。 const int型 INF = 0x3f3f3f3f 。 ストラクトE { int型V、NE、Cします。 } E [M]。 INTヘッド[N]、CNT = 1、N、M、ID [ 1007 ] [ 1007 ] [ 2 ]、TOL。 INT DIS [N]。 インラインボイド追加(INT U、INT V、INT C){ E [ ++ CNT] .V = V。E [CNT] .NE =頭部[ U]。E [CNT] .C = C。ヘッド[U] = CNT。 std ::スワップ(U、V); E [ ++ CNT] .V = V。E [CNT] .NE =頭部[ U]。E [CNT] .C = C。ヘッド[U] = CNT。 } #defineする PII対<整数を、整数> の#define Fiの第一 の#define SE第二 BOOL 行わ[N]。 INTのダイクストラ(INT S、INT T){ ため(INT iは= 1 ; I <= TOL; I ++ ) DIS [I] = INF。 DIS [S] = 0 ; std :: PRIORITY_QUEUE <はstd :: PII、のstd ::ベクトル<はstd :: PII>、のstd ::大きい<はstd :: PII>> QUE。 que.push(STD :: PII(0 、S))。 しばらく(!que.empty()){ std :: PII P = que.top()。que.pop(); int型のu = p.se。 もし(U == t)をブレーク。 もし([U]を行わ)続けます。 行わ[U] = 1 。 以下のために(INT iはヘッド= [U];私は= {E [I] .NE) int型、V = E [I] .Vと、 もし(DIS [V]> DIS [U] + E [I] .C){ 12月[V] = 12月[U] + E [i]の.C。 que.push(STD :: PII(DIS [V]、V))。 } } } 戻りDIS [T]。 } INT メイン(){ IO ::読み出す(N、M); INT、S = 1、T = 2 。 TOL = 2 。 以下のために(INT iが= 1 ; I <N; I ++ ) のための(INT J = 1 ; J <M、J ++ ) ID [I] [J] [ 0 ] = ++ TOL、ID [I] [J] [ 1 ] = ++ TOL。 以下のために(INT iが= 1 ; I <= N I ++ ) のための(INT J = 1 ; J <Mであり、j ++ ){ int型、U、Vを、 もし(I == N)U = S。 他のu = ID [i]の[j]の[ 1 ]; もし(I == 1)V = T。 他の V = ID [I - 1 ] [J] [ 0 ]; int型のC; IO ::読み込み(C); (U、V、C)を追加します。 } 以下のために(INT iが= 1 ; I <N; I ++ ) のための(INT J = 1 ; J <= Mであり、j ++ ){ int型、U、V。 もし(J == 1)U = S。 他の uは、IDを= [I] [J - 1 ] [ 1 ]; もし V =(J == M)、T。 他の V = ID [i]は[J] [ 0 ]; int型のC; IO ::読み込み(C); (U、V、C)を追加します。 } 以下のために(INT iが= 1 ; I <N I ++ ) のための(INT J = 1 ; J <Mであり、j ++ ){ int型、U = ID [I] [J] [ 0 ]、V = ID [I] [J]を[ 1 ]。 int型のC; IO ::読み込み(C); (U、V、C)を追加します。 } printf(" %dの\ n " 、ダイクストラ(S、T))。 リターン 0 ; }