アレックスは、全国の観光旅行に行くことにしました。
簡単にするための国が持っていると仮定しましょう n個のn都市や メートルのそれらを結ぶメートル双方向の道路。アレックスは、市内に住んでいる の Sと、最初はそれにあります。別の都市を比較するために、アレックスは、各都市にスコアを割り当てられた wが、私は興味深い都市がアレックスに思えるほど高くなっているのWi。
アレックスは、彼が2回連続で任意の道路を使用しない場合にのみ、彼の旅行は興味深いものになると考えています。アレックスは都市に来た場合には 、Vの街からV U Uを、彼は旅の次の都市として選択することもで接続された任意の都市 のV都市以外の道路で、V、 U U。
あなたの仕事は、アレックスは、彼が訪問したすべての都市の上に合計スコアを最大化する方法で、自分の街をお手伝いすることです。アレックスは彼の旅行中に存在し、数回あった場合でも、各都市のためのスコアは、最高1回にカウントされることに注意してください。
入力の最初の行に2つの整数を含んでいる N n及び m個(M、1 ≤ N ≤ 2 ⋅ 10 5、1≤n≤2⋅105 0 ≤ M ≤ 2 ⋅ 10 5の数である0≤m≤2⋅105)国の都市や道路。
2行目は含ま N nは整数であり 、W 1 、W 2 、... 、W N(W1、W2、...、WN 0 ≤ W iは≤ 10 9 0≤wi≤109)のすべての都市のスコアです。
次の m個の m行は、道路の記述を含みます。これらの各 m個の Mラインは、2つの整数を含んでいる U Uと V族(V 1 ≤ U 、Vの≤のn個のこの道路で接続された都市である1≤u、v≤n)。
何市が道路で自身に接続されていないと、最終的には、唯一の道路を使用して、他のものにすべての都市から行くことが可能であるが、任意の2つの都市間の最大1つの直接的な道があることが保証されています。
最後の行が含まれ、単一の整数 、S、S(1 ≤ S ≤のn個の初期都市の数である1≤s≤n)。
訪問した都市のスコアの最大和である出力単一の整数。
5 7 2 2 8 6 9 1 2 1 3 2 4 3 2 4 5 2 5 1 5 2
27
12 10 1 7 1 9 3 3 6 30 10 1 1 2 1 3 3 5 5 7 2 3 5 4 6 9 4 6 3 7 6 8 9 4 9 10 6
61
問題解決レポート:このトピックは、彼だけが各辺の前提で次の行くように、解決すべき最長経路の一つであるが、右のポイントと最大値を歩きました。
後にすることができ、小型の最適化作業がある検索をバーストするDFSを使用して、ベクトル記憶を有効に利用することは、我々はsのアレイを格納するために使用されて開かれた
このノードの現在の値が行き止まりに右パス上のポイントに行って、暴力の残りの部分を見つけることができます。
ACコード:
#include <iostreamの> する#include <CStringの> する#include <cstdioを> する#include <アルゴリズム> の#include <cmath> の#include <ベクトル> 使用して 名前空間STD。 typedefの長い 長いLL。 const int型 MAXN = 2E5 + 100 。 ベクター < INT > エッジ[MAXN]。 【MAXN、W LL、[MAXN]です。 int型のマークは、[MAXN]、VIS [MAXN]、[MAXN]事前; ボイド DFS(INT V) { VIS [V] = 1 。 以下のための(int型= J 0、J <エッジ[V] .size(); J ++ ) { int型、U = エッジ[V] [J]; IF(VIS [U])// この点を介してU場合、それは説明されているV到着 { IF(!U =前[V])// vは父ノードuのない場合、vは死んで終わりではありません { マーク[V] = 1 ; } } 他// この時点の前にあったなしのuアクセス { 事前[U] = V; // 次に、uは父ノードVである DFS(U); //はuがDFSための出発点として継続 IF(マーク[U])マーク[V] = 1 ; //後のUでの検索が開発し続けることができれば、それは死んで終わりではありません、そして、vは死んで終わりではない 、他の S [V] = MAX(S [U]、S [V]); // uが開発を継続する方法はありません場合、それは行き止まりである } } のIF(!マーク[V]) S [V] + = W [V]; // 正しい道プラス行き止まりにそれは行き止まりである場合、すべてのポイントと 返す; } int型)(メイン { int型N-、M; CIN >> N- M; のための(INT I = 1 ; I <= N; I ++ ) { CIN >> [I]はW; } のmemset(S、0、はsizeof(S))。 memsetの(マーク、0、はsizeof (商標))。 memsetの(VIS、0、はsizeof (VIS))。 memsetの(前、0、はsizeof (PRE))。 int型のuを、V。 用(int型 I = 1 ; I <= M Iは++ ) { scanf関数(" %D%dの"、&U、およびV)。 エッジ[U] .push_back(V)。 エッジ[V] .push_back(U)。 } int型STは、 scanf関数(" %d個"、&ST); DFS(ST); // (I ++; iが<= N I = 1 INT)ため // { // COUT << I <<」「<< S [I] << ENDL。 // } LL ANS = 0、MAXX = 0 。 以下のために(int型 i = 1 ; iが= <N; iは++ ) { 場合(マーク[i])と ANS + = W [i]は、 MAXX = MAX(MAXX、S [I])。 } ANS + = MAXX。 coutの << ANS << てendl; }