질문 표면 :
https://www.luogu.org/problemnew/show/P3355
해결 방법 :
水题 염색 + 최소 비율.
#INCLUDE <cstdio> #INCLUDE <CString을> #INCLUDE <iostream> #INCLUDE <벡터> #INCLUDE <큐> #DEFINE RI 레지스터의 INT #DEFINE N 50000 #DEFINE의 INF 1,000,000,007 #DEFINE의 S 0 #DEFINE T (n 개 * n 개의 + 1) 사용 스페이스 성병; CONST의 INT DX [] = {- 2 - 2 - 1 - 1 , 1 , 1 , 2 , 2 }, DY [] = { 1 - 1 , 2 -2 - 2 , 2 , 1 , - 1 }; INT의 N, M, X, Y, g [ 250 ] [ 250 ]; 구조체 그래프 { 벡터 < INT > w로; 벡터 < INT > 혼성 [N]; INT의 CUR [N], D [N]; 보이드 의 add_edge ( int로 U, INT의 V, INT의 {W1) // COUT << << U ","V << << ''<< W1 << ENDL; to.push_back (V); w.push_back (W1); ED [U] .push_back (to.size () - 1 ); to.push_back (U)] w 0 ); 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] 크기는 (); 나는 <L을, 난 ++ ) { INT의 E = ED [X] [I]; 만약 (w [E] && D [X] + 1 < D [내지 [E]) { D [내지 [E] = D [X] + 1 ; q.push (내지 [E]); } } } 리턴 D [T] < INF; } INT DFS ( INT (X), INT의 제한) { 경우 (X == T || 제한!의) 복귀 한도 INT의 TOT = 0 ; 대 (RI 및 I = CUR [X] 난 <ED [X] 크기는 (); 나는 ++ ) { INT의 E = ED [X] [I]; 경우 (d [내지 [E] == D [X] + 1 && w [E]) { INT의 F =DFS ([E], 분 (한계, w [E])); 경우 (F!) 계속 ; w [E] - = F; [w 1 ^ E] + = F; TOT + = F; LIMIT- = F; 만약 (! 제한) 반환 TOT; } } 반환 TOT; } INT의 dinic () { INT RET = 0 ; 반면 (BFS ()) { memset 함수 (현재, 0 , 는 sizeof (현재)); RET + = DFS (S, INF); } 반환 RET를; } } G; 값 int () {메인 scanf와 ( " %의 D % d에 " , N, m); 대 (RI I = 1 ; I <= m; 내가 ++ ) { 는 scanf ( " % d 개 %의 D ' , X, Y); g [X] [Y]는 = 1 ; } INT의 합 = 0 ; 대 (RI I = 1 ; I <= N; I ++ ) 용 RI (J = 1 , J <= N; J ++) 경우 (!의 g [I] [J]) { 합 ++ ; 경우 ((나는 J) % + 2 == 0 ) { G.add_edge (S를, N * (I-1 ) + J, 1 ); 대 (RI K = 0 ; K < 8 ; 케이 ++ ) { INT의 NX = 난 DX [K], NY = J +에 +를 DY [K]을; 경우 (NX> = 1 && NX <= N && NY> = 1 && NY <= N && g [NX] [뉴욕] == 0 ) G.add_edge (N *을 (I- 1 ) + J, N * ( NX- 1 ) + NY, INF); } } 또 G.add_edge (N *을 (I- 1 ) + J, T, 1 ); } COUT << 합 G.dinic () << ENDL; }