略奪計画

https://loj.ac/problem/10096

タイトル説明

  ATM機の後に奪われた強盗を停止するには、開始ノード番号1強盗、バーノードから行く準備ができて誰か、お金強盗の最大量を(求めるが所有する各ノードのATM機を知られている金額は、道路を通じて繰り返すことができ、お金)。

考え

  私たちは、強連結成分のために検討し、彼は確かに終わっ強連結成分にすべてのお金を取得し、任意のノードに達するので、我々はポイントを減らすことができます。この点は、各点ポイント還元後強連結成分の総重量の量です。我々DAGは、ポイントのために縮小した後、明らかにこの絵の中で最も長い道を見つけるために右の点の右側に変換することができます。ここでは、spfaリアライズを使用することができる最長の道路ですが、ここで我々は唯一の出発点に参加するトポロジカルソートを使用することができますので、トポロジの使用を避けることが、他に参加できない0ポイントで、それ以外の場合は、実現には、比較の到達点に到達しないだろう複合体は、最も直接的な短絡は、実際のトポロジーよりもはるかに遅いではありません。

コード

#include <ビット/ STDC ++ H>
 使用して 名前空間STDを、
CONSTの INT N = 5E5 + 10、M = 5E5 + 10 

構造体のエッジ
{ 
    int型のX、Y。
} E [M]。

int型V [N]。
INT NXT [M]、[M]、ヘッド[N]に、[N]、W、TOT。
ボイド add_edge(int型のx、int型の Y、INT V)
{ 
    NXT [ ++ TOT = 頭部[X]。
    ヘッド[X] = TOT。
    【TOT]へ = Y。
    W [TOT] = V。
} 

INT INT)(リード
{
    RES = 0、W = 1 チャー CH = GETCHAR()。
    一方、(CH < ' 0 ' || CH> ' 9 '){ 場合(CH == ' - ' = W) - 1 ; CH = GETCHAR();}
     一方(CH> = ' 0 ' && CH <= ' 9 '){RESの=(RES << 3)+(RES << 1)CH- + ' 0 ' ; CH = GETCHAR();}
     戻り * RES W。

 DFN [N]、低[N]、ST [N]、CO [N]、合計[N]、トップ、COL、IDX。
無効 tarjan(INT U)
{ 
    DFN [U] =低[U] = ++ IDX。
    ST [ ++トップ] = U;
    以下のためにint型 I =ヘッド[U]は、I; I = NXT [I])
    { 
        int型 V = 乃至[I]。
        もし(!DFN [V])
        { 
            tarjan(V)。
            低[U] = 分(低[U]、[V]低いです)。
        } 
        そう であれば(!CO [V])に
            ロー[U] = ([V] DFN低い[U])分。
    } 
    場合([U] == DFN低[U])
    { 
        共[U] = ++ COL。
        和[COLは] = V [U]を。
        一方、(ST [トップ] =!U)
        { 
            共[ST [トップ] = COL。
            和[COL] + = V [ST [トップ]。
            - トップ; 
        }
         - トップ。
    } 
} 

int型M。
ボイドリビルド()
{ 
    TOT = 0 
    memsetの(頭、0はsizeof (ヘッド))。
    以下のためのint型 I = 1; I <= M; iは++ 
    { 
        int型、U = CO [E [I] .X]、V = CO [E [I] .Y]。
        もし(!U = v)の
            add_edge(U、V、合計[V]); 
    } 
} 

int型DIS [N]を。
BOOL [N]を存在します。
ボイド spfa(int型の)
{ 
    キュー < INT > Q。
    DIS [S] =和[S];存在する[S] = 1 
    q.push(S); 
    一方、(!q.empty())
    { 
        int型、U = q.front(); q.pop()。
        [U]は存在 = 0 以下のためにint型 I =ヘッド[U]は、I; I = NXT [I])
        { 
            int型 V = 乃至[I]。
            もし(DIS [V] <DIS [U] + W [I])
            { 
                DIS [V] = DIS [U] + W [i]は、
                もし(![V]が存在)
                { 
                    存在する[V] = 1 
                    q.push(V); 
                } 
            } 
        } 
    } 
} 
int型のED [N]。
INT のmain()
{ 
    int型N、S、P。
    N = read()は、M =読む();
    以下のためにint型 iは= 1 ; I <= M; iが++ 
    { 
        intは X =読み取る()、Yは= )(読み取ります。
        add_edge(X、Y、0 ); 
        E [I] .X = xであり、e [i]を.Y = Y。
    } 
    のためにint型 i = 1 ; iが<= N; iが++ 
        V [I]。= READ(); 
    S =(読み取り); P = 読み取ります()。
    以下のためにint型 I = 1 ; I <= P; iが++ 
        ED [I]。= READ();
    以下のためのint型 I = 1私は++; iが<= N 場合!(DFN [i])とtarjan(I)。
    リビルド(); 
    spfa(CO [S])。
    int型 ANS = 0 ;
    以下のためにint型 I = 1 ; I <= P、iは++ 
        ANS = MAX(ANS、DIS [CO [ED [I]]])。
    printf(" %dの" 、ANS)。
}

 

おすすめ

転載: www.cnblogs.com/fangbozhen/p/11728898.html