まず、「 回前にいた頂点へ戻れない」という条件がない場合を考えます。
を、頂点 から 回移動して頂点 にいるときの最大スコアとすると、頂点 の隣接頂点を として、 と更新できます。
しかし、今回は直前にいた頂点へ戻ることが禁止されています。そのため、現在の頂点だけでなく、直前の頂点も覚える必要があります。
有向辺 に対して、 を「頂点 から 回移動し、最後に と移動したときの最大スコア」とします。到達不可能な状態は とします。
最初の移動について、頂点 と隣接する頂点 に対して とします。
最後に と移動した後、次に と移動することを考えます。直前にいた頂点へ戻れないため、 である必要があります。よって、遷移は
となります。
この式をそのまま計算すると、各辺 について のすべての隣接頂点を調べるため、計算量は次数の二乗に依存してしまいます。
そこで、各頂点 について、 の値が大きい方から 個を管理します。
頂点 から へ移動するとき、最大値を与える直前の頂点が でなければ、その最大値を使えます。一方、最大値を与える直前の頂点が なら、その状態から へ戻ることはできないため、 番目に大きい値を使います。
除外される候補は直前の頂点が である状態だけなので、最大値と第 最大値を持てば十分です。
各移動回数について、まずすべての有向辺 を調べて、各頂点 に到達する状態の最大値と第 最大値を求めます。その後、各有向辺 について、使用可能な方の値に を加えて次の状態を更新します。
回移動した後の頂点 の答えは、 に到達するすべての状態の最大値です。すべて到達不可能なら を出力します。到達可能な経路の最大スコアが負の場合は、その負の値をそのまま出力することに注意してください。
時間計算量は です。