Codeforces1204C。アンナ、Svyatoslavと地図(貪欲+フロイド)

トピックへのリンク:ポータル


 

効果の件名:

所与のn <= 100有向グラフ、およびパスp、最小シーケンス必要のP V、パスは、V Pの連続すべての点を通過するようになっています。


 

アイデア:

実際には、我々はすべての重要なポイントのために、パスvにいくつかの重要なポイントを尋ねる質問の意味を作ることです。v 私は、Vに私は+ 1つの、最短の長さは、Vに等しいIからV I + 1つの系列pにおけるこれら二つの点貧しい添字、およびVI VI + 2の最短の長さは、VI、VI + 2添字pは配列の差よりも小さいです

DIS [U]は[V]を示している場合:タイトルに最短経路の長さUからVへ、有向グラフを与えられました。その後:

。1、P 1及びP mは重要なポイントです。

2は、DIS [U] [P場合uは、最後の前に臨界点であると仮定するとI + 1 ]!= DIS [U] [P I ] +。1、PIは、次のキーです。

その後、任意の2点フロイド前処理の間の最短パスを使用し、O(m)は、配列P上に実行されるすべてのキーポイントを取得することができ、答えがあります。


 

コード:O(N 3 + M)

#include <ビット/ STDC ++。H>
 に#define高速IOS :: sync_with_stdio(偽)、cin.tie(0)、cout.tie(0)
 の#define N 105
 の#define M 1000005
 の#define INF 0x3f3f3f3f
 の#define MK(X )(1 << X)// マスクxが整数超える場合意識
の#define x.size())SZ(X)((INT)
 の#define LSON(X)(X << 1)
 の#define rsonを(X) (X << 1 | 1)
 の#define MP(a、b)はmake_pair(B)
 の#define ENDL '\ N'
 の#define lowbit(X)(X&-x)

使用して 名前空間はstdを、
typedefの長い 長いLL。
typedefをダブルデシベル。

/ * *高速読み取り* * / 
テンプレート <型名T> 
インラインボイドリード(T&X){
    X = 0TのFG = 1チャー CH = GETCHAR()。
    一方、(!isdigit(CH)){
         場合(CH == ' - ')FG = - 1 
        CH = GETCHAR()。
    }
    一方、(isdigit(CH))X = X * 10 + CH- ' 0 '、CH = )(GETCHAR。
    X = FG * X;
}
テンプレート <型名T、型名...のArgs> 
インラインボイドリード(T&X、Argsの&...引数){(引数...)を読み取り、(X)を読み取ります。}

INTのN、M。
INT [N] [N]。
BOOL カント[N] [N]。
int型P [M]。

ボイドFolyd(){
    memsetの(カント、はsizeof カント)。
    int型のk = 1 ; kは<= N; ++ k個){
         ためint型 I = 1は iが++; iがn = <)であれば(!I = K){
             ためのint型 J = 1、J <= N; J ++ )であれば(j!= I && J!= K){
                 場合([I] [J]> [I] [K] + [K] [J])
                    [i] [j]は [I] [K] + = [K] [j]を。
                他の 場合([I] [J] == [I] [K] + [K] [J]){
                    カント[i] [j]は = ;
                }
            }
        }
    }
}

ベクトル < int型 > ANS;
int型のmain()
{
    (n)を読み出します。
    以下のためにint型 i = 1 ; iが++; iが<= N ){
         ストリング S。cinを>> 秒;
        INT J = 1 ; J <= nであり、j ++ ){
             場合(J == I)
                [I] [J] = 0 ;
            それ以外の 場合(S [J- 1 ] == ' 1 ' 
                [I] [J] = 1 他の
                [I] [J] = 1E5;
        }
    }
    (m)を読み出します。
    以下のためにint型 I = 1 ; I <= M; iは++ ){
        (P [I])を読み出します。
    }
    Folyd();
    あなたと、p = [ 1 ];
    ans.push_back(U)。
    以下のためにint型、I = 2 ; I <= M; iが++ ){
         場合([U] [P [I]]> [U] [pは[I- 1 ]])
             続けます
        U = P [I- 1 ]。
        ans.push_back(U)。
    }
    ans.push_back(P [M])。
    COUT << ans.size()<< ENDL。
    以下のためにint型 i = 0 ; I <SZ(ANS); iは++ ){
        printf(" %d個の%のC "、ANS [i]は、I == SZ(ANS) - 1' \ N ''  ' )。
    }
    リターン 0 ;
}
コードの表示

 

おすすめ

転載: www.cnblogs.com/Lubixiaosi-Zhaocao/p/11634811.html