bzoj3575 最短路 SPFA 道路堵塞

2021-09-05 03:23:11 字數 3057 閱讀 3950

description

a國有n座城市,依次標為1到n。同時,在這n座城市間有m條單向道路,每條道路的長度是乙個正整數。現在,a國

交通部指定了一條從城市1到城市n的路徑,並且保證這條路徑的長度是所有從城市1到城市n的路徑中最短的。不幸

的是,因為從城市1到城市n旅行的人越來越多,這條由交通部指定的路徑經常發生堵塞。現在a國想知道,這條路

徑中的任意一條道路無法通行時,由城市1到n的最短路徑長度是多少。

input

第一行是三個用空格分開的正整數n、m和l,分別表示城市數目、單向道路數目和交通部指定的最短路徑包含多少條道路。

按下來m行,每行三個用空格分開的整數a、b和c,表示存在一條由城市a到城市b的長度為c的單向道路。

這m行的行號也是對應道路的編號,即其中第1行對應的道路編號為1,第2行對應的道路編號為2,…,第m行對應的道路編號為m。

最後一行為l個用空格分開的整數sp(1)…,,sp(l),依次表示從城市1到城市n的由交通部指定的最短路徑上的道路的編號。

2output

l行,每行為乙個整數,第i行(i=1,2…,,l)的整數表示刪去編號為sp(i)的道路後從城市1到城市n的最短路徑長度。

如果去掉後沒有從城市1到城市n的路徑,則輸出一1。

sample input

4 5 2

1 2 2

1 3 2

3 4 4

3 2 1

2 4 3

1 5

sample output

題解

首先有乙個性質

刪去一條邊之後走的邊一定是

1走一些最短路邊 然後走一些非最短路邊 然後再走一堆最短路邊到n

根據這個就可以搞事了

不妨先把所有最短路邊刪掉

列舉每條邊依次加入可以跑的邊中 每次就讓當前這條邊去跑spfa

比較好玩的就是這個dis不需要清空,一清空就穩的n

2n^2

n2了啊因為你發現dis是單調不增的,所以完全可以直接在上面的基礎跑

如果走到了一些在最短路上的點,就把當前這條路徑扔進堆裡,順便記錄一下最後沒有跑的最短路邊是哪一條

然後掃一遍就完事

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define ll long long

#define mp(x,y) make_pair(x,y)

#define pll pair

#define pii pair

using

namespace std;

inline

intread()

while

(ch>=

'0'&&ch<=

'9')

return x*f;

}int stack[20]

;inline

void

write

(int x)if(

!x)int top=0;

while

(x)stack[

++top]

=x%10

,x/=10;

while

(top)

putchar

(stack[top--]+

'0');}

inline

void

pr1(

int x)

inline

void

pr2(

int x)

const

int maxm=

200005

;const

int maxn=

100005

;struct nodea[maxm]

;int len,last[maxn]

;void

ins(

int x,

int y,

int c)

int d[maxn]

,n,m,l;

queue<

int> li;

priority_queue

,greater

> heap;

bool is[maxn]

,vis[maxn]

,no[maxm]

;int fr[maxn]

,ba[maxn]

,lin[maxm]

,s[maxm]

,pre[maxn]

,tot;

void

spfa

(int st)if(

!vis[y]

)vis[y]

=true

,li.

push

(y);}}

}}intmain()

for(

int i=

1;i<=l;i++

) s[

++tot]

=n;is[s[tot]]=

true

;for

(int i=l;i>=

1;i--

)ba[s[i]

]=ba[s[i+1]

]+a[lin[i]

].c;

// for(int i=1;i<=tot;i++)printf("%d ",s[i]);

// puts("");

memset

(d,63

,sizeof

(d))

;d[1]=

0;spfa(1

);for(

int i=

1;i<=l;i++

)return0;

}

最短路 spfa (一)

最短路 spfa 首先建立起始點a到其餘各點的 最短路徑 首先源點a入隊,當佇列非空時 隊首元素a 出隊,對以a為起始點的所有邊的終點依次進行鬆弛操作 此處有b,c,d三個點 此時路徑 狀態為 在鬆弛時三個點的最短路徑估值變小了,而這些點佇列中都沒有出現,這些點 需要入隊,此時,佇列中新入隊了三個結...

SPFA 最短路問題

簡單的說,spfa就是通過佇列 來實現的求最短路徑的演算法 首先,要用到乙個鄰接表來儲存各頂點之間的關係 包括起點u,終點v,以及u,v之間的權值w 然後就是構造spfa函式 第一步 對dis 用來存從源點到各頂點的最短距離 初始化為 inf 乙個很大的數例如0x3f3f3f3f 對 vis 陣列初...

最短路 SPFA演算法

spfa 是bellman ford的佇列優化,時效性相對好,時間複雜度o ke 與bellman ford演算法類似,spfa演算法採用一系列的鬆弛操作以得到從某乙個節點出發到達圖中其它所有節點的最短路徑。所不同的是,spfa演算法通過維護乙個佇列,使得乙個節點的當前最短路徑被更新之後沒有必要立刻...