P3627は、[[APIO2009]計画を略奪問題への解決策 -

すべての夜4時間GOO

P3627 [APIO2009]

略奪プログラム(https://www.luogu.org/problemnew/show/P3627)

 



答えが繰り返させる(図の最長の鎖の長さが指示することを見ることは容易です

私はDPよ!

図リングが、DPの仮定を満たしていない何の後遺症を持っていないかもしれません

私はtarjanます!

(あなたが強すぎます)

強連結成分がtarjan点を縮小した後、相互に到達することができるであろうに同じ点で、強いリンク各成分の合計値が全バンクの値となる点として

完了ポイント還元後、我々は、2つの点に接続された強連結成分に、元の接続側が新しいマップを再構築する場合に二つの点(これはパイプループないで同じ強連結成分であれば?)

その後もともと、読んで読んで......最長の道を模索BFSを書きたい、気持ちになるspfaは(叫び笑)

最後に、我々はすべてのポイントを列挙し、すべての強連結成分最長の道路の出発点を計算し、判断更新の答え上のバーがあります

#include <ビット/ STDC ++ H>
 の#defineが長い長いっ
 の#define 0x7FFFFFFFでINF
 使用して 名前空間STDを、
INTのN、M。 
#define MAXN 500009 
ベクトル < int型 > 息子[MAXN]。
INT [MAXN] C。
ブールバー[MAXN]。
ボイド追加(int型のx、int型のY)
{ 
    息子[X] .push_back(Y)。
} 
INT S、P。
int型DFSN [MAXN]、[MAXN] lowlink。
int型STA [MAXN]。
int型のトップ= 0 ;
int型 dfs_clock = 0; 
 のInt scc_cnt = 0 ; // 強連結成分の数は、
int型 SCC [MAXN]; // 強連結成分の各点
INTヴァル[MAXN]; // 各点の強連結成分の和の値が配置されています
INT Q [MAXN];
 INT Vyの[MAXN]; // の合計値の各強連結成分のための
空隙 dfs_scc(INT X)// Tarjan !!! 
{ 
    DFSN [X] = lowlink [X] = ++ dfs_clock; 
    STA 【 ++トップ] = Xは、
     のためにint型 I = 0 ;私は<ソン[X] .size();私は++ 
    { 
        int型今=息子の[X] [i]は、
        もし(!DFSN [今])
        { 
            dfs_scc(今)。
            lowlink [X] = 分(lowlink [X]、[今] lowlink)。
        } そう であれば(!SCC [今])
        { 
            lowlink [X] = 分(lowlink [X]、[今] DFSN)。
        } 
    } 
    もし(lowlink [X] == DFSN [X])
    { 
        scc_cnt ++ int型 ANS = 0 ;
        int型のp = 0 ;
        一方(STA [トップ]!= X)
        { 
            Q [ ++ P] STA [トップ] =; // ヒントを掘る:qは、配列のレコード、ポイントレコード内の強連結成分である、グローバル変数qはmemsetとせずに、開いていなければならない
             // 場合あなたは再帰でのqを定義するたびに、スタックが破裂します!ローカルハニーエラーは羅区は何ら問題は井出ない、起こります!
            = + ANS C [STA [トップ]; 
            SCC [STA [トップ - ] = scc_cnt; 
        } 
        トップ - ; 
        SCC [X] = scc_cnt; 
        Q [ ++ P] = X; 
        ANS + = C [X] ; 
        Vyの[scc_cnt] = ANS;
         のためのINT I = 1 ; I <= P; I ++ 
        { 
            ヴァル[Q [I]=  ANS。
        } 
    } 
} 
構造体ノード{
     int型X、Y。
} E [MAXN] ;; 
ベクター < INT > NEWMAP [MAXN]。
INT  、D [MAXN] [MAXN]。
構造体の点{
     int型のx、ステップと 
}。
INT メイン()
{ 
    scanf関数(" %d個の%のD "、&​​N、&M)。
    以下のためにint型 I = 1 ; I <= M; iは++ 
    { 
        int型のX、Y。
        scanf関数(" %dの%のD "、およびX&Y)。 
        (x、y)を追加します。
        E [i]は.X = X、E [i]を.Y = Y。
    } 
    のためのint型 i = 1 ; iが<= N; iが++ 
    { 
        scanf関数(" %のD "、&C [I])。
    } 
    のscanf(" %D%dの"、&​​S&P)。
    memsetの(バー、0はsizeof (バー));
    int型 iは= 1 ; I <= P iが++ 
    { 
        int型のX; 
        scanf関数(" %のD "、& x)は、
        バー[X] = 1 ; 
    } 
    のためのINT I = 1 ; I <= N; I ++ 
    { 
        IF(!dfs_scc(I)DFSN [I]); 
    } 
    のためのINT I = 1 ; I <= M、Iを++ )// 2の一端側が同じ強連結成分であってはならない
    {
         IF(SCC [E [I] .X]!= SCC [E [I] .Y])
        { 
            NEWMAP [SCC [E [I] 。.X]一back(SCC [E [I] .Y]); 
        } 
    } 
     
    キュー < INT > Q; 
    q.push(SCC [S]); 
    D [SCC [S] = ヴァル[S]。
    一方(q.empty(! ))// 全体の検索、ない、実際にはSPFAある
    {
         int型 XX = q.front();
         int型 X = XX; 
        q.pop(); 
       // のprintf( "X:D%D%\ N-"、X 、xx.step); 
        のためint型 I = 0 ; I <NEWMAP [X] .size();私は++ 
        { 
            int型へ= NEWMAP [X] [I];
             IF(D [に対する]> = D [X] VY +)へ] 続行 ; // 同様の緩和操作...... 
            D [に対する] = MAX(D [する]、D [X] + VY)へ]; 
            q.push()へ; 
        } 
    } 
    int型 = ANS 0 ;
     のためのInt I = 1。 ; I <= N-; I ++は
    { 
        IF(バー[I])// この時点では、バー、答えについて、我々の統計がある場合のその強連結成分
        { 
            ANS = MAX(ANS、D [SCC [I]); 
        } 
    } 
    のprintf(" %d個の\ N- " 、ANS);
     戻り 0 ; 
}

 

おすすめ

転載: www.cnblogs.com/lzy-blog/p/11229001.html