トピックリンク:https://www.luogu.com.cn/problem/P3376
参考ブログ:https://www.cnblogs.com/SYCstudio/p/7260613.html
EdmondsKarpアルゴリズムに基づいてDinic最大フローアルゴリズムは、拡張より方向を行う、階層グラフBFSの概念と結合され、DFSに増強パスの数を見つけることができ、アルゴリズムの複雑さはOである(| E | * | V | ^ 2回)が、アルゴリズムの速度が速いことを説明した時の理論よりも実際にはもっと複雑です。思想Dinicアルゴリズムは、彼が多くのAの時間を持っている場合は、各ポイントのために、そしてあなたは、拡張スクラッチSRCから開始するように増強パスの検索を行うのではなく、ポイントから各枝に分岐することができ、ようなものです。DFSは、分岐した後、現在のポイントに戻りますたびに、分岐が今、この流れのサイズを更新するために費やすことができ、使用可能な次の分岐流が低下します。
コードは以下の通りであります:
1の#include <ビット/ STDC ++ H> 2 使用して 名前空間STDを、 3符号なしのtypedef int型のUI。 4のtypedef 長い 長LL。 5符号なしのtypedef 長い 長いULL。 6 の#define PFのprintf 7 の#define MEM(A、B)のmemset(A、B、はsizeof()) 8 の#define prime1 1E9 + 7 9 の#define prime2 1E9 + 9 10 の#define PI 3.14159265 11 の#define LSON Lを、半ば、室温<< 1つの 12 の#definersonミッド+ 1、R、RT << 1 | 1 13 の#define scand(X)のscanf( "%のLLF"、&x)は 14 の#define iは=(INTのためのF(I、B)、I <= B; I ++) 15 の#defineスキャン(A)のscanf( "%d個"、&) 16 の#define MP(a、b)はmake_pair(()、(B)) 17 の#define P対<整数、整数> 18 #define DBG(引数)COUT <<#1引数<< ":" <<引数<< ENDL。 19 の#define INF 0x7ffffff 20インラインINT リード(){ 21件 のint ANS = 0、W = 1 。 22 CHAR CH = GETCHAR()。 (!isdigit(CH)){ 場合(CH == ' - ')W = - 1 ; CH = GETCHAR();} 24 ながら(isdigit(CH))ANS =(ANS << 3)+(ANS << 1)+ CH- ' 0 '、CH = GETCHAR()。 25の リターン ANSは* wは、 26 } 27 28 CONST INT MAXN = 1E5 + 10 。 29 整数N、M、S、T。 30 INT CNT = 0 。 31 INTヘッド[MAXN]、NXT [MAXN * 10 ]、D [MAXN]。 32 構造体ノード{ 33 int型V、W。 34 } P [MAXN * 10 ]。 35 int型電子。 36 ボイド addedge(INT U、INT V、INT w)の 37 { 38 P [E] .V = V。 39 P [E] .W = W。 40 NXT [E] = 頭部[U]。 41 頭[U] = E ++ 。 42 } 43 ブール BFS(INT SRC、int型のシンク)// 确定BFS序 44 { 45 MEM(D、0 ); 46は D [SRC] = 1 ; 47 キュー< INT > Q; 48 q.push(SRC); 49 ながら(!Q.empty()) 50 { 51は、 INT CUR = Q.フロント(); 52である ()q.pop; 53である ため(INT I =ヘッド[CUR];〜I Iは= NXTは、[I])が 54である { 55 のint V = P [I] .V; 56である IF(D! [V] && P [I] .W)//は、基準点はなく、バック縁されていないかを決定 57 { 58 D [V] = D [CUR] + 1 。 59 q.push(V)。 60 } 61 } 62 } 63 であれば(D [シンク])リターン 真。 64 リターン はfalse ; 65 } 66 int型の DFS(INT S、INT 流れ) 67 { 68 であれば(S == T)リターンフロー。 69 INTは =使用0 。 70 のために(INT Iは、ヘッド= [S];〜I; Iは= NXT [I])を 71であり、 { 72 のint V = P [I] .V、W = P [I] .W; 73は、 IF(D [V] == D [S] + 。1 && W> 0)// 考えDinicアルゴリズムに従って、前方にのみ移動することができ、BFS順序年生縁 74 { 75 INT TMP = DFS(V、分(flow- 使用され、W))を、 76 IF(TMP> 0 ) 77 { 78 P [I] .w- = TMP; // 順流と逆流の側縁部を更新する、 79 P [I ^ 1 ] .W + = TMP; // nはエッジは、その対応する逆の側が前方側+1偶数である 80 + =中古TMP; // 開始点からの流れが最も流れで、流量ニーズを更新するために費やさ 81 IF(中古==フロー)BREAK ; 82 } 83 } 84 } 85 リターン使用され; 86 } 87 INT Dinic() 88 { 89 INT ANS = 0 ; 90 ながら(BFS(S、T)) 91である { 92 ANS + = DFS(S、INF); 93 } 94 リターンANS; 95 } 96 INT main()の 97 { 98 // freopenは( "INPUT.TXT"、 "R"、標準入力)。 99 // freopenは( "output.txtと"、 "W"、STDOUT); 100件 のstd ::イオス:: sync_with_stdio(偽); 101 N =読み取る()、M =)を読み込む()、S =(読み取り、T =は(読み取り)。 102 MEM(ヘッド、 - 1); MEM(NXT、 - 1 )。 103 INTのU、V、W。 104 、F(I、1 、M) 105 { 106 Uが読み取ら=()、V =(読み取り)、= W )(読み取ります。 107 addedge(U、V、W); addedge(V、U、0 ); 108 } 109 INT maxflow = dinic()。 110 PF(" %dの\ n " 、maxflow)。 111 }