カーニハン-Ritchie--ガウスの消去にUVa10828戻ります

問題の意味

プログラム制御フローグラフは等しい後続の各ノードに接続された各ノードからの確率が与えられます。後続ノードのない一つの完全な後、全体の処理を終了します。ノード番号が1であると、プログラムは常に起動します。あなたの仕事は、各ノードが実行の所望の数を取得し、ノードの数を照会することです。ノード数$ N <10 $。

分析

有向非巡回グラフを直接再帰関係を解くことができる場合には、メモリの検索を使用して解きます。

この問題は、リングのみ記載されている方程式、ガウスの消去法を使って方程式の解を持っているかもしれないが。

$ I $ $ D_I $用ノードのセットは、実行の所望の数は$ X_I $です。前駆体のための3つのノードは、B、Cの$ノードの$ I $を$ている、式$ X_I = X_A / D_A + x_b / D_B + X_C / D_C $挙げることができます。

$ X_I間違って無限大にあるいは代数的方法によって$ 0の場合、私たちは実際の意味を検討し、

どのノードが数え切れないほどにそれを実行するために期待されていますか?最終状態に到達することができないそれらのノード(すなわち、非最終状態はサイクルされています)。

どのノードがそれの2倍を実行するために期待されていますか?それができないものに出発点からの出発点です。

私たちはまず、無限大とゼロのポイントを見つけるまず、フロイド推移閉包を見つけることができます

ガウスを使用している場合 - この前処理のJordanの消去法を回避することができる、とき$ A [i]は[I] = A [i]と[N] = 0 $ $ X_I = 0 $と$ A [i]と[ I] = 0 $が、$ A [i]と[N]> 0 $ $ $ X_Iが正の無限大であるとき(この結論が明確に表示されます

#include <cstdioを> 
する#include <cmath> 
の#include <アルゴリズム> 
の#include <CStringの> 
する#include <ベクトル>
 使用して 名前空間STD。

constの ダブル EPS = 1E- 8 ;
CONST  INT MAXN = 100 + 10 
typedefをダブルマトリックス[MAXN] [MAXN]。

// 结果为A [i]が[N] / A [i]は[I] 
ボイド gauss_jordan(行列A、int型N)
{ 
    int型I、J、K、R。
    (i = 0 ; iがn <; iは++ 
    { 
         //行rの絶対値と第i行の交換から選択され、 
        R = iが、
         ため(J = I +は1。 ; J <N-; J ++ IF(FABS([J] [I])> FABS([R] [I] ))R&LT = J;
         IF(FABS([R&LT] [I])<EPS)   続行 ;       // この行をあきらめ、直接次の行
        IF!(R&LT = I)   のために(J = 0 ; J <= N- ; J ++ )スワップ([R&LT] [J]、[I] [J]); 

        // i番目の行の削除を除く他の行との
        ための(K = 0 ; K <N-; K ++)   IF( != K I)
             のために(N = J; J> = I; J)A [K] [J] - A = [K] [I] / A [I] [I] * A [I] [ J]; 
    }
}

行列A; 
INTのN、D [MAXN]。
ベクター < INT > プレ[MAXN]。
int型のINF [MAXN]。

INT のmain()
{ 
    int型カセ= 0 一方、(scanf関数(" %のD "、&​​N)== 1個の && N)
    { 
        memsetの(D、0はsizeof (d)参照)。
        以下のためにint型 i = 0 ; iがn <Iは、++は予め[I] .clear())。

        int型、B;
        しばらく(scanf関数(" %d個の%d個"、&​​A&B)== 2 && A)
        { - ; B - ;    // 0から数 
            D [A] ++;      // 。ノードの次数が追加され1 
            プレ[B] .push_back( A); 
        } 

        //  
        のmemset(A、0はsizeof (A))
         のためのINT I = 0、I <N - 、I ++は
        { 
            [I] [I] = 1 ;
             のためのINT J = 0 ; J <PRE [I] .size(); J ++
                [I] [プレ[I] [J]]- = 1.0 / D [プレ[I] [J];
             IF(I == 0)A [I] [N-] = 1 ; 
        } 

        // 式、無限可変マークの溶液
        gauss_jordan(A、N-)
        のmemset (INF、0はsizeof (INF));
         のためのINT I = N- 1、Iは> = 0 ; i-- 
        { 
            IF(FABS([I] [I])<EPS && FABS([I ] [N - ])> EPS)INF [I] = 1 ;   // 直接溶液無限可変アウト

            INT J =私は+ 1、J <N-; J ++)    //変数と、関連する無限可変無限可変
                IF(FABS([I] [J])> EPS && INF [J])INF [I] = 1 ; 
        } 

        int型Q 、U; 
        scanfの(" %のD "、&Q); 
        のprintf(" ケース#1%のD:\ N- "、++ 加瀬);
         一方、(Q - 
        { 
            scanfの(" %のD "、&U)、
            U - ;
             IF(INF [U])のprintf(" 無限\ N- " );
               printf(" %.3fする\ n "、ファブ([U] [U])<EPS?0.0:[U] [N] / A [U] [U])。
        } 
    } 
    戻り 0 
}

質問HHにおけるUVAの手の公式ウェブサイトで初めて、トピックのリンク

 

から:

「アルゴリズムコンテストエントリー古典的なトレーニングマニュアル」 - Liuru嘉、と陳鳳

 

おすすめ

転載: www.cnblogs.com/lfri/p/11528335.html
おすすめ