フェイス質問
https://www.luogu.org/problem/P3171
問題の解決策
// luogu-判定部有効-O2 の#include <cstdioを> する#include <iostreamの> の#include <CStringの> の#include <キュー> の#include <ベクトル> の#define LL長い長い の#define里レジスタint型 の#define N 550 の#define INF 1000000007 の#define M 150000 使用して名前空間はstdを、INTのN、M。 INT デュ[N]。構造体ノード{ int型Uと、LLのD; ブール演算子 <(constのノード&RHS)のconst { リターン D> rhs.d。 } }。 構造体グラフ{ ベクトル < INT > [N]に、LEN [N]。 LL DIS [N]。 BOOL VIS [N]。 ボイド(add_edge のint、int型 B、int型のC){ [A] .push_back(B)に、LEN [A] .push_back(C); [B] .push_backに(A)LEN [B] .push_back(C); } ボイドダイクストラ(){ PRIORITY_QUEUE <ノード> Q。 memset(DIS、0x3fを、はsizeof (DIS))。 DIS [ 1 ] = 0 ; q.push((ノード){1、0 })。 一方、(!q.empty()){ int型のx = q.top()をU。q.pop(); もし(VIS [X])続けます。 VIS [X] = 1 。 用(RI I = 0、L =に[X] .size(); iはLを<; iは++ ){ int型、Y = に[X] [I]; もし(DIS [Y]> DIS [X] + LEN [X] [I]){ DIS [Y] = DIS [X] + LEN [X] [I]; q.push((ノード){Y、DIS [Y]})。 } } } } } G。 構造体graph2 { ベクター< INT > ED [N << 1 ]。 int型の CNT、W [M << 1 ]乃至[M << 1 ]。 INT D [N << 1 ]。 INTの CUR [N << 1 ]。 ボイド add_edge(int型、int型 B、INT C){ ED [A] .push_back( ++ CNT)。[CNT] = Bへ; W [CNT = C。 ED [B] .push_back( ++ CNT)。[CNT] =であり; W [CNT] = 0 ; } ボイドmakegraph(){ PRIORITY_QUEUE <ノード> Q。 q.push((ノード){ 1、0}); CNT = - 1 。 一方、(!q.empty()){ int型のx = q.top()をU。q.pop(); 用(RI I = 0、L = g.to [X] .size(); iはLを<; iは++ ){ int型、Y = g.to [X] [I]; もし(g.dis [Y] == g.dis [X] + g.lenは、[X] [I]){ add_edge(2 * X、2 * Y- 1 、INF)。 q.push((ノード){Y、g.dis [Y]})。 } } } のための(RI i = 1 ; iが<= N; iが++)add_edge(2 * I- 1、2 * I、デュ[I])。 } BOOL BFS(){ キュー < INT > Q。 memsetの(D、0x3fを、はsizeof (d)参照)。 D [ 2 ] = 1 ; q.push(2 )。 一方、(!q.empty()){ int型のx = q.front()。q.pop(); 用(RI I = 0、L = ED [X] .size(); iはLを<; iは++ ){ int型、E = ED [X] [I]; もし(W [E] && [X] D + 1 < = D [X] + D [乃至[E]]){ D [E] [する] 1 。 ([E]に)q.push。 } } } 戻り D [ 2 * N- 1 <= 2 * N。 } INT DFS(int型のx、int型の制限){ 場合(Xの== 2 * N- 1 ||限界!)戻り限界; int型 =使用0 ; 用(RI&I = CUR [X]、L = ED [X] .size(); iはLを<; iは++ ){ int型、E = ED [X] [I]; 場合(D [X] + 1== D && [E] [する]W [E]){ int型 = F DFS([E]に、分(限界、W [E]))。 もし(!f)を続けます。 W [E] - = F。[W 1 ^ E] + = F。 使用リミット-側= + = F F。 もし(制限== 0)リターン使用。 } } リターン使用。 } LLのdinic(){ LLのRET = 0 。 一方、(BFS()){ memsetの(CUR、0、はsizeof (CUR))。 RET + = DFS(2 、INF)。 } 戻りRET。 } } G2。 INT メイン(){ scanf関数(" %d個の%のD "、&N、&M)。 int型、B、C; 用(RI i = 1 ; I <= M; iは++ ){ scanf関数(" %D%D%D "、&、&B、&C)。 g.add_edge(A、B、C)。 } のための(RI i = 1 ; iが<= N; iが++)のscanf(" %dの"、&デュ[I])。 g.dijkstra(); G2.makegraph(); COUT << G2.dinic()<< ENDL。 ; }