最短路變短了 最短路

2022-06-30 18:54:15 字數 1313 閱讀 7330

題目鏈結

題解鏈結

首先,在原圖上以點 \(1\) 為起點跑一遍最短路,處理出 \(dis1[i]\);

然後,把所有邊反向以點 \(n\) 為起點跑一遍最短路,處理出 \(dis2[i]\);

當把第 \(i\) 條邊反向後,假設該邊的為 \(u\to v\),邊權為 \(c\)。修改之後的圖與原圖相比,可能替代原來最短路變成新最短路的路徑只有可能是 \(1\to v \to u \to n\)。

因此,需要判斷該條路徑和原最短路的關係。

當 \(dis1[v]+dis2[u]+c時,表示最短路變短,否則沒有。

證明:對於該式子:

\[dis1[v]+dis2[u]+c

\]\(dis2[u]\) 為反向圖時求的最短路,把邊反向時對其值沒有影響。\(c\) 的值也不變。但邊 \(u\to v\) 反轉後,可能會對 \(dis1[v]\) 產生影響,只需要對 \(dis1[v]\) 進行討論。

當 \(dis1[v]\) 並沒有經過邊 \(u\to v\) 時,\(dis1[v]\) 並沒有發生改變,可以直接用於判斷。

當 \(dis1[v]\) 經過了邊 \(u\to v\) 時,那麼當該邊反向後,\(dis1[v]^\geq dis1[v]\),如果仍用 \(dis1[v]\) 來判斷的話,這條新的路徑的長度會比原來路徑 \(1\to u\to v\to n\) 要多 \(c\),因此必然不可能,所以用 \(dis1[v]\) 仍然可以判斷。

#include #define pb push_back

using namespace std;

typedef long long ll;

typedef pairp;

const ll inf=1e16;

const int n=1e5+5;

struct edge

e[n<<1];

vectorg[2][n];

priority_queue,greater>que;

ll dis[2][n];

void read(int &x)

while(isdigit(ch))

x*=f;

}void dij(int s,int f,int n)}}

}int main()

dij(1,0,n);

dij(n,1,n);

read(q);

while(q--)

return 0;

}

最短路 最短路徑問題

題目描述 平面上有n個點 n 100 每個點的座標均在 10000 10000之間。其中的一些點之間有連線。若有連線,則表示可從乙個點到達另乙個點,即兩點間有通路,通路的距離為兩點直線的距離。現在的任務是找出從一點到另一點之間的最短路徑。input 共有n m 3行,其中 第一行為乙個整數n。第2行...

最短路徑演算法 最短路

在每年的校賽裡,所有進入決賽的同學都會獲得一件很漂亮的t shirt。但是每當我們的工作人員把上百件的衣服從商店運回到賽場的時候,卻是非常累的!所以現在他們想要尋找最短的從商店到賽場的路線,你可以幫助他們嗎?input 輸入包括多組資料。每組資料第一行是兩個整數n m n 100,m 10000 n...

最短路(最短路之積)

首先考慮暴力維護,顯然極端資料就會炸裂,那麼用什麼來維護呢?考慮乙個很 nb的公式log n m log n log m ok,這道題到此結束 我們只要把乘積轉化為對數,最後再還原就可以了,也不用考慮精度問題,本蒟蒻試著用pow,然後它死了。includeusing namespace std co...