前置芝士:
我的floyd基礎知識講解
說白了,floyd本質上就是乙個dp:
k為外層狀態,i和j為內層列舉。floyd完整狀態其實是:\(f[k][i][j]\)表示以前k個點為轉移點(即編號為1~k的點可以被用來鬆弛),從\(i\)到\(j\)的最短路徑。
每條最短路徑都是以k為基礎的,對於未列舉進k的點將不被考慮進最短路徑的鬆弛,k也就作為整個圖的最短路徑的前提條件,那麼自然作為最外層狀態轉移。
給你一張無向圖,給你每乙個節點的資訊t表示當前節點在時間為t以及以後可以到達。
翻譯一下,也就是可以考慮進最短路的鬆弛。
樸素想法,對於每個t,我們可以列舉每乙個結點,如果結點的\(t>\)當前詢問的時間,將不被考慮進圖中。每一次詢問在重新建完圖後跑一邊floyd,並在判斷起點村莊s到終點l能否到達,如果能到達輸出即可。
很明顯,t的死死的。每次跑一遍floyd實在是太浪費了時間,而且題目中的資料是遞增的。出題人給你的優化條件你怎麼能不用呢。
k表示考慮了1~n的節點作為可鬆弛點,也就是說:編號1到n的節點都能夠到達。
換句話說,1到n節點滿足了被加入最短路集合的條件。
對於這道題,從暴力思路可以看出,乙個節點被加入最短路集合的條件就是當前節點的t值小於等於詢問的時間t。而出題人給你的t是單調的。那麼,我們設上一次詢問的時間為\(t_\),這一次詢問的時間為\(t_\),以t為floyd最外層狀態k,對於\(t_\)之前的k我們就不必再跑一遍了,從上一次能夠到達的編號為now的節點開始往後判斷節點的t是否小於詢問的t,直到大於詢問的t為止。
原因很好理解,節點的t隨著編號的上公升而上公升,而詢問的t又上公升,那麼考慮過的節點一定滿足加入最短路集合的條件,也就不用再跑一遍floyd(\(n^2\))的部分了。
核心**:
q=read();
while(q--)
while(ch>='0'&&ch<='9')
return x*f;
}int n,m,a[n],u,w,v,q,judge=-1,dis[n][n],now;
inline void add(int from,int to,int w)
inline void dp(int now)
} return 0;
}
希望看完這篇博文後能夠加深各位對floyd的理解!
完結撒花
P1119 災後重建
原題鏈結 一開始直接想跑最短路 看了看詢問次數 放棄了 然後果斷看了題解 floyd 用啥都不會用它的好嗎 平常的最劣選擇 但是 它就是正解 floyd的原理 就是列舉中點 這裡 因為出題人 已經把詢問排好了序 只需要判斷中點 有沒有重建完成 把它加入圖中 include include inclu...
P1119 災後重建
我覺得這個題出的很好,讓我對floyd 演算法有了乙個更深的理解。floyd 是乙個求多源最短路徑的演算法,演算法的內容很簡單。這個演算法的主要思路,就是通過其他的點進行中轉來求的兩點之間的最短路。因為我們知道,兩點之間有多條路,如果換一條路可以縮短距離的話,就更新最短距離。而它最本質的思想,就是用...
P1119 災後重建
b地區在 過後,所有村莊都造成了一定的損毀,而這場 卻沒對公路造成什麼影響。但是在村莊重建好之前,所有與未重建完成的村莊的公路均無法通車。換句話說,只有連線著兩個重建完成的村莊的公路才能通車,只能到達重建完成的村莊。給出b地區的村莊數n,村莊編號從0到n 1,和所有m條公路的長度,公路是雙向的。並給...