질문의 의미 : 짧은 길이가보다 n을 방법 1의 이동을 만드는 방법을 물어 있도록 가장 저렴한 방법의 일부를 차단할 수 있습니다 이제 N 포인트 m 가장자리를 줄
아이디어 : 최단 시작을 구축하고 대부분의 단락 회로 다이어그램과 동시에 우리의 최대 유량 최소 잘라 내기 요구하면서 실행보고
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#INCLUDE <비트 / stdc ++ H.> 사용 스페이스 성병; CONST 이중 PI ACOS = (- 1.0 ); CONST의 INT maxn 1E4 + = 7 ; CONST INT INF = 0x3f3f3f3f ; CONST 두 EPS 1e- = 6 ; 타입 정의 긴 긴 LL; CONST LL 모드 1E9 + = 7 ; 구조체 에지 { int로 , 옆; w LL; }; 에지 E [maxn << 1 ]; INT의 헤드 [maxn, CNT; INT힘 [maxn]; LL의 D [maxn]; 공극 초기화 () { CNT = 0 ; memset 함수 (헤드, 0 , 는 sizeof (헤드)); memset 함수 (힘, 0 , 는 sizeof (힘)); memset 함수 (d, INF, 는 sizeof (d)); } 공극 추가 ( int로 U, INT의 V, INT w) { E [ ++ CNT] = {헤드 [U, V, W}; 헤드 [U] = CNT; } 공극 DIJ ( INT의 S) { priority_queue <쌍 <LL, INT >>큐; D [S] = 0 ; q.push (make_pair ( 0 , S)); 반면 (! {q.empty ()) INT U = q.top () 제.; q.pop (); 경우 (힘 [U]) 계속 ; 힘 [유] = 1 ; 위한 ( int로 ; I I = I = 헤드 [유] {E [i]는 다음 내용) 의 INT V = E가 [I] .TO; INT w = E [I] .W; 경우 (d는 [V]>는 D [U]는 + w) { D는 [V] D [U] + = w 단계; q.push (make_pair ( -D [V] V)); } } } } 구조체의 가장자리 { LL 에서 , 캡, 흐름; 에지 ( int로 U, INT의 V, INT의 C, INT의 F) 의 (U), (V), 캡 (c) 흐름 (F) {} }; 구조체 Dinic { INT의 N, M, S, T; 벡터 <엣지> 에지; 벡터 < INT > G [maxn]; INT D [maxn 같이, [maxn] CUR; 불리언 힘 [maxn]; 무효화 INIT ( INT의 {N) 위한 ( int로 I = 0 ; I <N이 나 ++ G [I]하는 명확한 ())를; edges.clear (); } 공극 AddEdge ( INT 에서 , INT 에, INT의 CAP) { edges.push_back (에지 ( 발 에, 캡, 0 )); edges.push_back (에지에 ( 행 , 0 , 0 )); m = edges.size (); G [ 발 ] .push_back (m - 2 ); .push_back [을] G (m - 1 ); } 부울BFS () { memset 함수 (마주, 0 , sizeof 연산자 (마주)); 큐 < INT > Q; Q.push (S); D [S] = 0 ; 힘 [S] = 1 ; 반면 (! Q.empty ()) { INT (X) = Q.front (); Q.pop (); 위한 ( int로 I = 0 ; I <는 G를 [X] 크기는 (); 나는 ++ ) { 에지 및 E = 가장자리 [G [X] [I]; 만약 (! 힘 [e.to] && e.cap> e.flow) { 힘 [e.to] =1 ; D [e.to] = D [X] + 1 ; Q.push (e.to); } } } 복귀 힘 [t]을; } LL DFS ( INT의 X, LL a) { 경우 (X == t || == 0 ) 돌려 단계; LL 흐름 = 0 , F; 대 ( INT 및 I = CUR [X] 난 <G를 [X] 크기는 (); 나는 ++ ) { 에지 및 E = 가장자리 [G [X] [I]; 경우 (d [X] + 1 == D [e.to] && (F = DFS (e.to, 분 (a, e.cap - e.flow)))> 0 ) { e.flow + = F; 에지 [G [X] [I]를 ^ 1 ] .flow - = F; 흐름 + = F 단계; - = F; 경우 (A == 0 ) 체류 ; } } 리턴 흐름; } LL Maxflow ( INT S, INT의 t) { 이것 -> S에서의 = S; 이 -> t = t; LL 흐름 = 0 ; 반면 (BFS ()) { memset 함수 (현재, 0 ,를 sizeof (현재)); 흐름 + = DFS (S, INF); } 리턴 흐름; } } dinic; INT 비안 [maxn] [ 3 ]; INT 의 main () { INT의 t; scanf와 ( " %의 D " , t); 반면 (t-- ) { 초기화 (); INT의 N, m; scanf와 ( " %의 D % d에 " , N, m); 위한 ( int로 난 = 1 ; I <= m 내가 ++ ) { INT X, Y, C; scanf와 (" % D % D % D ' , X, Y, 및 C); 비안 [I] [ 0 ] = X를; 비안은 [I]는 [ 1 ] = y로; 비안 [I] [ 2 ] =의 C; 추가 (X, Y, C); } DIJ ( 1 ); dinic.init (N); 위한 ( int로 I = 1 ; I <= m; 내가 ++ ) { 경우 (d [비안 [I] [ 1 ]] == D [비안 [I] [ 0 ] + 비안 [I] [ 2 ]) { dinic .AddEdge (비안 [I] [ 0 ], 비안 [I] [ 1 ], 비안 [I] [ 2 ]); } } 의 printf ( " % LLD \ 없음 " , dinic.Maxflow ( 1 , N)); } }