この質問は、データの範囲が比較的小さいので、この方法は非常に暴力的です。
アイデア:
彼の周りのグリッドを持つすべてのグリッドでもグリッドの値の重み(0または1)に接続するように、各グリッドの状態を押します。その後、我々は最短が最初から最後までの障害の最小数である、最短を実行するために、すべてのn個の正方形のグリッドを列挙します。我々は、彼が唯一のk等しいチャンス未満を取ったかどうかを見ての障壁を除去した後、すべてのほとんどの短絡を列挙して、2点間の距離を計算し、その後、あなたは最大を取ることができます。
コードは以下の通りであります:
#include <ビット/ STDC ++ H> 使用して 名前空間STDを、 const int型 MAXN = 1E6 + 7 。 構造体ノード{ int型のNXT、ヴァル、であり; }エッジ[MAXN * 3 ]。 int型のヘッド[MAXN]、CNT; int型 NUM [ 550 ] [ 550 ]。 INTヴァル[ 550 ] [ 550 ]。 チャー S [ 550 ] [ 550 ]。 INTのN、M、T。 ボイド追加(int型のx、int型の Y、INT V){ エッジ[++ CNT] .nxt = 頭部[X]。 エッジ[CNT] .TO = Y。 エッジ[CNT] .val = V。 ヘッド[X] = CNT。 } PRIORITY_QUEUE <ペア< 整数、整数 >> Q。 二重 DIST(int型のx、int型の Y、INT XX、INT YY){ リターン(ダブル)SQRT((X-XX)*(X-XX)* 1.0 +(Y-YY)*(Y-Y-Y)* 1.0 ) ; } 二重ANS。 BOOL VIS [MAXN]。 INT DIS [MAXN]。 ボイドダイクストラ(INT X){ memsetの(DIS、88、はsizeof (DIS))。 memsetの(VIS、0、はsizeof (VIS))。 DIS [X] = 0 ; q.push(make_pair(0 、X)); 一方、(q.size()){ int型、U = q.top()は、第2。 q.pop(); もし(VIS [U])続けます。 VIS [U] = 真; 以下のために(int型 I =;私=頭部[U] {エッジ[I] .nxt) のint = Vをエッジ[I] .TO。 もし(DIS [V]> DIS [U] + エッジ[I] .val){ DIS [V] DIS [U] + = [I] .valエッジ; q.push(make_pair( - DIS [V]、V))。 } } } } int型のmain(){ scanf関数(" %D%D%D "、&N、&M&T)。 以下のために(int型 i = 1 ; iが<= N; iは++ ){ ための(int型 J = 1 ; J <= Mであり、j ++ ){ CIN >> S [I] [J]。 NUM [I] [J] =(I-1)* M + J。 もし(S [I] [J] == ' 1 ')のval [I] [J] = 1 。 } } / * のための(I = 1をint型、iが<= N; iが++){ ため(INT J = 1; J <= Mであり、j ++){ のprintf( "%dの"、NUM [I] [J])。 } のprintf( "の\ n"); } * / 用(int型 i = 1 ; iが<= N iが++ ){ ため(INT J = 1 ; J <= Mであり、j ++ ){ 場合(I> 1)(NUM [I] [j]を追加し、NUM [I- 1 ] [j]を、ヴァル[I- 1] [J])。 もし(iはN <)を追加(NUM [I]、[J]、NUM [iが+ 1 ] [j]を、ヴァル[I + 1 ] [J])。 もし(j> 1)を追加(NUM [I]、[J]、NUM [I]、[J- 1 ]、ヴァル[I]、[J- 1 ])。 もし(J <M)を追加(NUM [I]、[J]、NUM [I]、[J + 1 ]、ヴァル[I]、[J + 1 ])。 } } のための(int型 i = 1 ; iが<= N iが++ ){ ため(INT J = 1 ; J <= Mであり、j ++ ){ ダイクストラ(NUM [I] [J])。 用(INT X = 1; X <= nであり; x ++ ){ ため(int型、Y = 1 ; Y <= M、Y ++ ){ 場合(DIS [NUM [X] [Y] +ヴァル[I]、[J] <= T)ANS = MAX(ANS、DIST(I、J、X、Y))。 } } } } のprintf(" %.6lfする\ n " 、ANS)。 リターン 0 ; }