ときに科学廃棄の元の行列のパワー、そして唯一の行列の最適化再帰を使用して、グラフ理論は、土地を横たわっているこの瞬間に遭遇しました。
昨日は、長期qpow隣接行列が逃げる上のプログラムのビューのパス上のポイントに、例を持っている、高齢者のクラスにポイントから数のために右側を聴きます。
だから、自分自身の小さなマップ塗装、手が真であることが判明し、行列を走った、私はその理由を考えるようになりました。
実際には、感触のようfloyedと、[I] [J] C行列 =ΣA[I] [K] * B [K] [j]を、kはブレークポイントとしてfloyedされ、毎回一つの操作次に、2つのステップを取るbに、プログラムの数の変化が存在することになる、ステップを取るように見えるK作製することができる1、K 2、K 3 ......過去、このプロセスの電源を入れマトリックスは加速しました。
これは右側ではないように、最初のものは、実際のポイントであることを除いて、9点1に分割することができる。他のすべての仮想点であり、各点が一方向側に直接接続され、右の1であり、それはによって寄与を表します過去において、右点直接仮想点Iから点Jのヴァルの第1の値に、したがって元の問題と等価です。
残りは考えることが、qpowと誰が最終的に出力され、コードを見ていないと思います。
#include <iostreamの> する#include <アルゴリズム> の#include <CStringの> する#include <cstdioを> する#include <cmath> の#include <ベクトル> の#include <キュー> の#include <スタック> の#include < セット > の#include <地図> 使用して 名前空間はstdを、 const int型 P = 2009 ; int型N、K。 チャー CH [ 300 ]。 int型 CAL(int型 I、int型J){ リターン(I- 1)*9 + J; } 構造体マトリックス{ INT X [ 120 ] [ 120 ]。 友人マトリックス演算子 * (行列B、行列){ 行列C。 memset(CX、0、はsizeof (CX))。 // c.debug(); 以下のために(int型 i = 1 ; iが<= N; I ++ ) のための(INT J = 1 ; J <= N; J ++ ) のための(INT K = 1 ; K <= N; kは++ ) CX [I] [J] =(CX [I] [J] + AX [I] [K] * BX [K] [J])%のP。 リターンC; } ボイド追加(int型、int型B){ X [A] [B] = 1 。 返します。 } ボイドench(){ ため(int型 i = 1 ; iがn = <; iは++ ) X [i]は[I] = 1 。 返します。 } ボイドデバッグ(){ ためには、(int型 i = 1 ; iが<= N; I ++){ ため(INT J = 1 ; J <= N; J ++ ) COUT << X [I] [J] << " " 。 coutの << てendl; } } ボイドPUT(){ のprintf(" %dは"、X [ 1 ] [N- 8 ])。 返します。 } }。 ボイド qpow(int型K){ 行列B、C。 c.ench(); // coutの<<てendl; // c.debug(); B =A; 用(; kは、kは>> = 1、B = B * b)の 場合(K&1)C = C * B。= C。 } int型のmain(){ scanf関数(" %D%dの"、&N&K)。 以下のために(int型 i = 1 ; iが<= N; iは++ ){ ための(int型、J = 1、J < 9 ; J ++ ) a.add(CAL(i、j)は、CAL(I、J + 1 ))。 scanf関数(" %sの"、CH + 1); 用(INT J = 1 ; J <= nであり、j ++ ){ 場合(CH [J] - ' 0 ' == 0)続けます。 a.add(CAL(I、CH [J] - ' 0 ')、CAL(J、1 ))。 } }、N * = 9 。 // a.debug(); qpow(K)。 // coutの<<てendl; // a.debug(); a.put(); リターン 0 ; }