看標題都知道講的是什麼,但為什麼特指是a*關於k短路的解法呢?
因為林蔭不會其他的。
能看到這篇部落格的估計也都知道k短路和a*分別是什麼了吧,下面只介紹一下估價函式
由於林蔭並沒有經過學術訓練,所以一下關於a*的理解均為感性,僅可作為oier速成知識點時的一點資料,
切莫作為演算法學術依據。
先思考一下,對於任意一條k短路,是不是均可寫成由一部分最短路和一部分其他路徑組成,而且這兩部分路徑還有且僅有乙個公共點。
說明:1.任何一條路徑都可以視為由其他到終點的路徑和終點到終點的最短路組成
2.哪怕前面的路徑上有環,最短路也一定和其他的路徑在環的出點上相連。因為一旦最短路和路徑上其他點相交,就代表該最短路上有環,那麼這條路徑就不是最短路。
好的,下面引入概念:估價函式!
實際上沒啥特別的,就乙個公式 f(x)=g(x)+h(x),f(x)是該路線的期望花費,g(x)是從起點到當前點的花費,h(x)是當前點到終點的最優花費。
那麼,我們在求解的時候是不是有個大致思路了?
k值越小的路徑的x點離起點越近(大概就這個意思,也可以認為越接近最短路的路線所使用的最短路越多)
那麼我們是否可以考慮先將h處理出來(建反圖,求單源最短路),然後維護乙個優先佇列,佇列裡面儲存乙個pair(f(x)和x點),那麼我們每次根據f(x)的值決定下乙個執行的點,如果x已經是終點了,就該統計答案統計答案,該返回返回,否則針對x計算出每乙個相連線的點to,求出f(to)後壓入佇列,直到完成k個路徑或者發現當前最短的一條路徑已經不滿足需求。
至於如何確定第k短路就知道了吧(由於有優先佇列,第乙個出來的一定是最短,第二個一定是次短,第三個一定是3th)。
下面放個**吧,例題cogs3227
嚴格來說這個並不算k短路,而是給定特殊限制,求滿足條件的路徑
#include#include#include
#include
using
namespace
std;
vector
int,int> > b[1001],fb[1001
];int vis[1001],dis[1001
];int
n,m,a1,a2,a3,s,f,ans,mx,t;
void
dij()}}
}void
astar()
else
return
; }
for(int i=0;i)
}}int
linyin()
for(int i=1;i<=m;i++)
scanf(
"%d%d
",&s,&f);
dij();
mx=dis[s]+1
; astar();
printf(
"%d\n
",ans);
return0;
}int
lwh()
return0;
}int mylove=lwh();
intmain()
完結撒花!!!
蒟蒻林蔭小複習 Splay
首先表示對yyb大佬的崇高敬意雖然大佬根本不知道林蔭是個神馬東西 在這裡學的 yyb大佬的教程!好吧,我回來填坑了!首先宣告一下定義 structp p t 150001 t陣列就是記錄整顆樹的陣列,v代表當前點的權值,ff代表當前點的父親,ch 0,1 分別代表左右子樹 左子樹上的元素小於根,右子...
蒟蒻林蔭小複習 克魯斯卡爾重構樹
這是乙個冷門到不能再冷門的東西,至於這東西有什麼用,且聽我慢慢道來。現在給定一張無向圖,每個點有乙個點權,每條邊有乙個邊權。現在給出許多詢問三元組 x,y,z 要求求出從x出發,只能走邊權不超過y的邊,所能走到邊權第z大的點的點權是多少?bzoj3551 如果離線的話,大佬們好像可以用主席樹套樹之類...
小蒟蒻的計算幾何學習初步
直線凸包 表示法 點用橫縱座標來表示,所以我們定義乙個結構體 而向量可以用乙個點表示,所以就直接當點來用 struct point typedef point vector 運算 四則運算 最簡單的普通的加減乘除運算高中和初中物理都學過,這裡就不做多的解釋了 vector operator vect...