すべての夜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 ; }