考える:脳+ 2部グラフマッチング
提出:1(クラスで話題)
ソリューション:
発見:彼らは質問の意味を満たす場合は、行と列がマッチした一から一でなければなりません(要件)、最大マッチングは$ N $でなければなりません。
私たちは道によってランクが質問の意味と一致状態に変換し、最大のマッチが千鳥持っている(ように見える)になるに交換することができるようになります、ことがわかりました。
だから、最大の一致は$ N $で判断するための基礎です。
#include <cstdioを> する#include <iostreamの> する#include <CStringの> する#include <アルゴリズム> の#define RレジスタINT 使用して 名前空間STDを、 #defineは、符号なしの長い長いULL の#defineっ長い長 の#defineポーズ(; iは<= 10000000000 ++ i)について(R I = 1) の#define IN freopenは( "NOIPAK ++における" STDIN、 "R") 位定義 freopenはをOUT( "out.out"、 "W"、STDOUT) 名前空間FREAD { 静的 チャー B [ 1 << 15 ]、* S = B * D = B。 JACK #ifndefの に#defineGETCHAR()(S == D &&(D =(S = B)+関数fread(B、1,1 << 15、STDIN)、S == D)EOF:* S ++) #endifの インラインINT G(){ R RET = 0、=解決1。登録のchar chのを。しばらく(!isdigit(CH = getchar関数()))修正= CH == ' - ' - ?1 :修正します。 DO RET = RET * 10 +(CH ^ 48)。一方、(isdigit(CH = GETCHAR()))。リターンのRET *の修正。 }インラインブールのisEmpty(CONST チャー&CH){ 戻り CH <= 36|| CH> = 127 ;} インラインボイド GS(CHAR *秒){登録チャー CHと、一方(のisEmpty(CH = GETCHAR()))。やる * S ++ = CHを; 一方(のisEmpty(CH =!GETCHAR()));} } 使用 FREAD :: Gと、使用FREAD :: GSを。 CONSTの INT N = 210 。 INT VIS [N]、[N]を予め、T、ANS、N、ティム。 ブール値E [N] [N]。 インラインBOOL DFS(INT U){ ための(RはV = 1 ; V <= N; ++ V)であれば [V](E [U] [V] && VIS =!TIM){ VIS [V] =ティム。もし {事前[V] = U(PRE [V] || DFS(PRE [V])!)。返す 真;} } 戻ります 偽。 } {main()の符号付き の#ifdef JACK #endifの T = G(); 一方、(t--){ANS = 0を、ティム= 0 。 memsetの(VIS、0、はsizeof(VIS))、memsetの(前、0、はsizeof(PRE))、memsetの(例えば、偽、はsizeof (e)参照)。 N = G(); 以下のための(R i = 1 ; iが<= N; I ++)以下のための(RのJ = 1 ; J <= N; ++ j)は、E [I] [J] = G(); 以下のための(R i = 1 ; iが<= N; ++ I)++ティム、ANS + = DFS(I)。 もし(ANS == N)のprintf(" はい\ nを" ); 他のprintf(" ノー\ nを" ); } }
2019年7月18日