フェイス質問
https://www.luogu.org/problemnew/show/P3324
問題の解決策
水の問題。
答え+ -half可能な最大の文章の流れ。
- 最大血流障害がモデルの使用に対処することに注意してください。
// luogu-判定部有効-O2 の#include <cstdioを> する#include <iostreamの> の#include <CStringの> の#include <ベクトル> の#include <キュー> の#define里レジスタint型 の#define N 505 の#define INF十億七 の#define T (N + M + 1) の#define EPS 1E-5を使用して名前空間STD。INTのN、M。 ベクター < 整数 > に、ED [N]。 ベクトル < ダブル > ワット。 INTのCUR [N]、D [N]。 二重の合計; int型 G [N] [N]、[N]、B [N]。 インラインint型リード(){ int型 = F 0、RET = 0。チャー CH = GETCHAR()。 一方、(CH < ' 0 ' || CH> ' 9 ')は、f | =(CH == ' - ')、CH = GETCHAR()。 一方、(CH> = ' 0 ' && CH <= ' 9 ')RET * = 10、RET + =(CH- ' 0 ')、CH = GETCHAR()。 リターン F - ?RET:RET; ボイド add_edge(INT U、INT V、ダブル W1、ダブルW2){ to.push_back(V)。w.push_back(W1)。ED [U] .push_back(to.size() - 1 )。 to.push_back(U)。w.push_back(W2)。ED [V] .push_back(to.size() - 1 )。 } BOOL BFS(){ キュー < INT > Q。 memsetの(D、0x3fを、はsizeof (d)参照)。 D [ 0 ] = 0 ; q.push(0 )。 しばらく(!q.empty()){ int型のx =q.front(); q.pop(); 用(RI I = 0、L = ED [X] .size(); iはLを<; iは++ ){ int型、E = ED [X] [I]; もし([E]> EPS && W D [X] + 1 < D [乃至[E]]){ D [乃至[E] = D [X] + 1 。 ([E]に)q.push。 } } } 戻り D [T] <= 1000000 。 } ダブル DFS(INT X、二重限界){ 場合(!X == T ||限界)リターンリミット。 ダブル TOT = 0 ; にとって(RI&I = CUR [X]; iが[X] .size()編<; iは++ ){ int型、E = ED [X] [I]; もし(D == D [X] + [E]に】1 && W [E]> EPS){ ダブル F = DFS([E]に分(限界、W [E]))。 もし(F <EPS)を続けます。 W [E] - = F。[W 1 ^ E] + = F。 TOT + = F。リミット-側= F。 もし(限界<EPS)戻りTOT。 } } 戻りTOT。 } ダブルdinic(){ ダブル RET = 0 。 同時に(BFS()){ memsetの(CUR、0、はsizeof (CUR))。 RET + = DFS(0 、INF)。 } 戻りRET。 } ブールチェック(ダブルT){ w.clear()。to.clear(); 用(RI i = 0 ; iがM + <= N + 1 ; iが++ ED [I] .clearを())。 用(RI i = 1 ; I <= M; iは++)add_edge(0、Iは、T *のB [i]は、0 )。 用(RI I = 1 add_edge(M + I、T、[I]、; iが<= N I ++)は0 )。 用(RI I = 1、I <= M; I ++) のための(RIのJ = 1 ; J <= N; J ++)場合(G [I] [J])add_edge(I、M + J、INF、0 ); もし(dinic()+ EPS>合計)リターン 1。それ以外 の戻り 0 ; } int型のmain(){ N)=(読み取り; M = 読み取ります(); 用(RI i = 1 ; I <= N; iは++)[I] = 読み取ります(); 和 = 0.0 。 用(RI I = 1の合計+ =; iが<= N iが++)[I]を、 用(RI I = 1 [I] = B iが++; I <= M) (リード)。 にとって(RI I = 1 ; I <= M; I ++ ) のための(RI J = 1 ; J <= N; J ++)G [I] [J] = 読み取ります(); ダブルポンド= 0、RB = 10007 ; ダブル ANS = - 1 ; 一方、(RB-LB> 1E- 4 ){ ダブルミッド=(LB + RB)/ 2 。 もし ANS =半ば、RB =ミッド((MID)をチェックしてください)。他ポンド= ミッド; } のprintf(" %の.4lf " 、ANS)。 リターン 0 ; }