道路や路線
制限時間:1秒 メモリ制限:128メガバイトタイトル説明
ファーマージョンが調査する彼の牛乳販売プログラムのための新たな販売エリアです。T彼は牛乳の町(1 <= T <= 25,000)、第1Tしたかったです。Rによって物品との間の都市の道路(1 <= R <= 50,000は、R 1と番号付け)及びPルート接続(1 <= P <= 50,000、P 1と番号付け)。I I又はバイこれらの町Al(1 <=あい<= T)を接続する各道路(1 <=バイ<= T)、コストCIため。道路のために、0 <= CI <=万であるがルートを費やすことは驚くべきであり、使用済Ciは(-10000 <= CI <= 10,000)負であってもよいです。道は愛からのBiに、また双方向からの愛に、すべてのCIを過ごす、双方向です。ただし、航空会社のコントラスト、唯一の愛からのBiへ。バイへの愛からのルートがある場合は、保証は道路やルートの数によって愛バイから復帰することはできません。実際には、傲慢な最近のテロリストによるは、社会の調和のために、ことを確認するために、ポリシーの数を導入しました。世界がFJの牛が力にある認識されているように、彼はすべての町に牛を輸送する必要があります。彼は、送信S(1 <= S <= T)各町のための最も安いプランへの乳牛から町の中心を見つけるか、これが不可能であることを知りたいと思いました。
エントリー
* 1行目:第二列にT、R、P、及びS * R + 1:4つのスペースは整数を分離した3つの空間は、(道路で表される)整数分離:Al、Bi及び第一のCIを*スペースで区切られた3つの整数(ルートが表されている)::Al、Bi及びCI R + 2 R + P + 1つのラインに
輸出
* Tラインに1:何も出力「NOパス」が存在しない場合、私は、町に到達したSから最小コスト。
サンプル入力 のコピー
6 3 3 4
1 2 5
3 4
5 6 10
3 5 -100
4 6 -100
1 3 -10
サンプル出力 のコピー
NO PATH
NOのPATH
5
0
-95
-100
プロンプト
6つの町の合計。それぞれ5,5,10過ごし1-2,3-4,5-6間の道路があります。一方、3つの経路:3-> 5、
> 6 4- 1-> 3は、それぞれ、-100、-100、-10とります。町4でFJの町の中心部。
FJ開始する町から4頭の牛は、あなたが道路3号で、町に到達することができます。その後、彼らは町を5及び第6号のルートに到達します。
しかし、町1及び2に到達することは不可能です。
> 6 4- 1-> 3は、それぞれ、-100、-100、-10とります。町4でFJの町の中心部。
FJ開始する町から4頭の牛は、あなたが道路3号で、町に到達することができます。その後、彼らは町を5及び第6号のルートに到達します。
しかし、町1及び2に到達することは不可能です。
ソリューション:私は以下の点を最適化し、SPFAの最適化を使用して、最短のタイトルは、直接最短SPFA、その後、捕まる走り、プラスO3は同じカードになります。
ダブルエンドキューキューキュー両端キューに1. SPFA
2.キューが空でない、[V]、電流DISを決定し、キューの先頭は、次に小さな、簡単かつ迅速に更新の最初のチームの値と比較します
if
(!q.empty()&&dis[v]<dis[q.front()]) q.push_front(v);
else
q.push_back(v);
3.レビューSPFA、エッジング初期化ヘッド[] = - 1
SPFAキューでキューの距離にDISのステートメントを実行しますVIS [] []かどうかの起源
0 = INT_MAX memsetを可視に初期化DIS n個の点[]
DIS = 0原点フラグVIS = 1をキューに入れられました。
サイクルを実行し、すべてのエッジを横断するポイントに達すると、キュー番号から除去され、キューは、ポイントで更新されたときにDIS [V]> DIS [今] + EDG [I] .W他のポイントを更新し、キューをマークプラス
1つ の#pragma GCC最適化(3、 "Ofast"、 "インライン") 2の#include <ビット/ STDC ++ H> 3 使用して 名前空間STDを、 4 CONST INT N = 500000 。 5 INT 、N、R、P、S。 6 構造体SS 7 { 8 INT U、V、W、次。 9 } EDG [N]。 10 INT sumedg、ヘッド[N]。 11 ボイド addedg(intは U、int型 V、INT w)の 12 { 13 EDG [sumedg] = (SS){U、V、W、ヘッド[U]}。 14 頭[U] = sumedg ++ 。 15 } 16 のint DIS [N]。 17 BOOL VIS [N]。 18 ボイドspfa() 19 { 20 両端キュー< INT > Q。 21 のために(INT iが= 0 ; I <N + 10は、I ++)DIS [I] = INT_MAXは、 22 のmemset(VIS、0、はsizeof (VIS))。 23 q.push_back(S); 24 VIS [S] = 1 。 25の DIS [S] = 0 ; 26 長い 長い SUM1 = 0、SUM2 = 1 。 27 28 ながら(!q.empty()) 29 { 30 INT今= q.front(); q.pop_front()。 31 32 sum2-- 。 33 sum1- = DIS [今]。 34 35 ながら(SUM2 && SUM2 * DIS [今]> SUM1) 36 { 37 q.push_back(今)。 38 SUM1 + = DIS [今]。 39 今= q.front()。 40 q.pop_front()。 41 sum1- = DIS [今]。 42 } 43 44 VIS [今] = 0 ; 45 のために(INT - ;!私= iはヘッド[今] = 1 ; I = EDG [I] .next) 46 { 47 のint V = EDG [I] .V。 48 であれば(DIS [V]> DIS [今] + EDG [I] .W) 49 { 50の DIS [V] = DIS [今] + EDG [I] .W。 51 であれば(!VIS [V]) 52 { 53 VIS [V] = 1 。 54 もし(q.empty()&& DIS [V] <!q.push_front(V)DIS [q.front()]); 55 他q.push_back(V); 56 57 SUM1 + = DIS [V]。 58 SUM2 ++ ; 59 } 60 } 61 } 62 } 63 } 64 のint main()の 65 { 66 のscanf(" %D%D%D%D "、&N、&R、&P&S)。 67 のために(INT iが= 0 ; iが<= N; I ++)ヘッドを[I] = -1 ; 68 のために(INT iは= 0 ; I <R I ++ ) 69 { 70 INT U、V、W。 71 のscanf(" %D%D%D "、&U&V、およびW) 72 addedg(U、V、W)。 73 addedg(V、U、W)。 74 } 75 のために(INTは iは= 0 ; I <P; I ++ ) 76 { 77 INT U、V、W。 78 のscanf(" %D%D%D "、&U&V、およびW) 79 addedg(U、V、W)。 80 } 81 spfa()。 82 のために(INT iは= 1 ; iが<= N; I ++ ) 83 { 84 であれば(DIS [I] = INT_MAX!)のprintf(" %D \ n " 、DIS [I])。 85 他のprintf(" NOパス\ N " ); 86 } 87 リターン 0 。 88 }