質問UVA 10603--暗黙のマップ&&ダイクストラを注ぎます

タイトル

次の3つの能力を与える最初に水で満たされた唯一の最初の3杯、他の2つのカップの空の$カップC $、B、です。あなたは、少なくともどのくらいの水に$ Dの$ lのそれは持っている水のコップを作る必要がありますか?正確$ D $ Lをしないと、水のガラスは$ {D} $ dが$に近い<D $および '$ {D}の$ L' でありましょう。($ 1 \当量のA、B、C、Dの\の当量200 $)

分析

第1カップは、それから、状態$((v_0、V_1、V_2))$であると言って、水の第三のカップ$ V_2の$リットルあり、第2カップは、水の$ V_1 $リットルを有する水の$ v_0 $リットルを設定していますカップは、次の状態を注ぐ他のカップに向かって延長され、セットダウン水は、2つの状態間の距離です。ダイクストラと同様に、各キューは、それぞれの時間は、あなたの答えを更新し、最小距離から排出されることを保証することが可能です。

水の総量は変化しないので、それは$ v_0、V_1 $決定、$ V_2 $も決定されているので、状態の実際の数は$ 200 ^ 2 $です。

書式#include <cstdioを> 
する#include <CStringの> 
の#include <キュー>
 使用して 名前空間はstdを、

構造体ノード{
   int型 V [ 3 ]、DIST。
  ブール 演算子 <(constのノード&RHS)のconst {
     戻り DIST> rhs.dist。
  } 
}。

const  int型 MAXN = 200 + 5 int型のマークは[MAXN] [MAXN]、DIST [MAXN] [MAXN]、キャップ[ 3 ]、[MAXN] ANS。

ボイド update_ans(CONSTノード&U){
   int型 I = 0 ; iが< 3 ; iが++ ){
     int型、D = UV [i]は、
    もし(ANS [D] < 0 || u.dist <ANS [D])ANS [D] = u.dist。
  } 
} 

ボイド(解決int型int型 B、int型 C、int型の{d)を
  キャップ[ 0 ] =。キャップ[ 1 ] = B; キャップ[ 2 ] = C; 
  memset(ANS、 - 1はsizeof (ANS))。
  memsetの(マーク、0はsizeof (商標))。
  memset(DIST、 - 1はsizeof (DIST))。
  PRIORITY_QUEUE <ノード> Q; 

  ノード開始。
  start.dist = 0 ; 
  start.v [ 0 ] = 0start.v [ 1 ] = 0start.v [ 2 ] = Cと、
  q.push(スタート)。

  DIST [ 0 ] [ 0 ] = 0 一方、(!q.empty()){ 
    ノードU = q.top()。q.pop();
    もし(マーク[UV [ 0 ] [紫外線[ 1 ])続け; 
    マーク[UV [ 0 ] [UV [ 1 ] = 1 
    update_ans(U)。
    もし(ANS [D]> = 0破ります以下のためにint型 i = 0 ; iは< 3 ; I ++ のためのINT J = 0 ; J < 3 ; J ++)場合(!I = J){
         場合(UV [I] == 0 || UV [J] = =キャップ[J])を続けますINTの量=分(キャップ[J]、UV [I] + UV [J]) - UV [J]。
        ノードU2 = U; 
        u2.dist = u.dist + 量。//换成+1、就是求最少次数
        u2.v [i]は - = 量を、
        u2.v [J] + = 量。
        INT&D = DIST [u2.v [ 0 ] [u2.v [ 1 ]。
        もし(D < 0 || u2.dist < D){ 
          D = u2.dist。
          q.push(U2)。
        } 
      } 
  } 
  ながら(D> = 0 ){
     場合(ANS [D]> = 0 ){ 
      のprintf(" %D%D \ n "、ANS [D]、D)。
      返します
    } 
    D - 
  } 
} 

int型のmain(){
   int型T、A、B、C、D。
  scanf関数(" %のD "、&T)。
  一方、(T-- ){ 
    scanf関数(" %D%D%D%D "、&​​、&B、&C&D)。
    (A、B、C、D)を解きます。
  } 
  戻り 0 
}

 

おすすめ

転載: www.cnblogs.com/lfri/p/11455377.html