這是在一棵樹上求k短路
首先,根據題目定義的奇怪路徑,求u,v
u,vu,
v的路徑長度,跟根節點到u
uu和根節點到v
vv的路徑和是相等的,以為根節點到lca
(u,v
)lca(u,v)
lca(u,
v)的路徑會因為一正一負而被抵消掉。
d is
[i]dis[i]
dis[i]
可以在dfs
dfsdf
s中求出來。
然後根據深度,將奇數深度的放到a
aa,偶數的放到b
bb,將其分別排序,因為奇數+偶數一定等於奇數。 然後將其兩兩配對,用乙個堆來維護。
#include
#include
#include
#define ll long long
#define rep(i,x,y) for(register ll i=x;i<=y;i++)
using
namespace std;
ll n,k;
struct nodea[
200005];
struct nodd
;ll head[
100005
],tot,dep[
100005
],d[
100005
],d1[
100005
],d2[
100005
],list1,list2;
priority_queue q;
bool
operator
<
(const nodd &a,
const nodd &b)
void
add(ll x,ll y,ll z)
; head[x]
=tot;
}void
dfs(ll x,ll fa)
}int
main()
dfs(1,
0);rep
(i,1
,n)if
(dep[i]%2
==1) d1[
++list1]
=d[i]
;else d2[
++list2]
=d[i]
;sort
(d1+
1,d1+list1+1)
;sort
(d2+
1,d2+list2+1)
;if(list1*list2
return0&
printf
("stupid mike");
rep(i,
1,list1) q.
push
((nodd));
rep(i,
1,k-1)
);}printf
("%lld"
,q.top()
.z);
}
對頂堆(動態維護第k大 小)
對於動態維護第k小的問題,可以用乙個size為k的大根堆,來維護,大根堆的頂部元素即第k小元素,維護大根堆需要乙個小根堆,由小根堆向大根堆傳遞元素,即對頂堆。若當前大根堆size為k,第k 1小元素即小根堆的頂部元素 題目描述 保證b為增序 ac include include include in...
第K短路 嚴格第K短路
所謂k短路,就是從s到t的第k短的路,第1短就是最短路。如何求第k短呢?有一種簡單的方法是廣度優先搜尋,記錄t出佇列的次數,當t第k次出佇列時,就是第k短路了。但點數過大時,入佇列的節點過多,時間和空間複雜度都較高。a 是在搜尋中常用的優化,一種啟發式搜尋。簡單的說,它可以用公式表示為f n g n...
K短路 模板
a spfa演算法 1 將有向圖的所有邊正向 反向分別存入兩個不同的邊集 edges,edges1 中。用反向邊集,以所求終點t為源點,利用spfa或dijkstra求解出所有點到t的最短路徑,用dist i 陣列來表示點i到點t的最短距離。2 建立乙個優先佇列,將源點s加入到佇列中。3 從優先佇列...