#include <ビット/ STDC ++ H> 使用して 名前空間STDを、 INT、M、N、TOT = - 1、H [ 1005 ]、ANS = 0、TP = 0 。 構造体ノード{ INT から次は、休憩します。 int型最後; } E [ 10005 ]。 ボイド追加(int型のx、int型のy、int型Z){ TOT ++ 。 E [TOT] .next = H [X]。 H [X] = TOT。 E [TOT]。= X。 E [TOT] .TO =Y; E [TOT] .rest = Z。 } int型 DIS [ 1005 ]、G [ 1005 ]、[フロー1005 ]。 BOOL VIS [ 1005 ]; INTの BFS(INT S、INT T){ キュー < INT > Q。 DIS [S] = 0 ; (S)q.push; VIS [S] = 真。 一方、(!q.empty()){ int型、U = q.front(); VIS [U] = 偽; q.pop()。 以下のために(int型私は時間= [U];!I =( -1); I = E [I] .next){ 場合(DIS [E [i]は.TO]> DIS [U] + 1 && G [E [i]は.TO] ==( - 1)&& E [I] .rest> 0 ){ G [E [i]は.TO] = I。 流動[E [i]は.TO] = 分(フロー[U]、E [I] .rest)。 DIS [E [i]は.TO] = DIS [U] + 1 。 もし(VIS [E [i]は.TO] == 偽){ VIS [E [i]は.TO] = 真。 q.push(E [I] .TO)。 } } } } } int型EK(INT S、INT T){ ながら(1 ){ memsetの(DIS、から0x7f、はsizeof (DIS))。 memsetの(VIS、偽、はsizeof (VIS)); memsetの(フロー、から0x7f、はsizeof (フロー))。 memsetの(G、 - 1、はsizeof (G))。 BFS(S、T)。 もし(G [T] ==( - 1))戻り 0 ; ANS + = 流量[T]。 以下のための(int型P = T P =(S);!P = E [G [P]]。){ E [G [P]]休む。 - = [t]を流れます。 E [G [P]]最後。 = TP。 E [G [P] ^ 1 ] + = .rest フロー[T]。 } } } int型のmain(){ memsetの(H、 - 1、はsizeof (H))。 CIN >> N >> M。 以下のために(INT iが= 1 ; I <= M; I ++ ){ 追加(0、I、1 )。 追加(I、0、0 ); } 用(INT I = M + 1 ; I <= N; I ++ ){ 追加(I、N + 1、1 )。 追加(N + 1、I、0 ); } int型のX、Y。 一方、(scanf関数(" %D%D "、およびX&Y)=!{EOF) 追加の(x、y、1 )。 追加(Y、X、0 ); } EK(0、N + 1 )。 もし(ANS == 0 ){ COUT << "解決策!「 << ENDL; 出口(0 ); } COUT << ANS << ENDL; }
まあ、これは、ネットワークフロー問題です....部グラフの最大マッチングを行います
水が経つにつれて、あなたはハンガリーを行うに興味がある可能性があり、またはネットワークフローは、ヘクタールを味