a*:我已經忘了怎麼寫了,反正n=30,m=1000都能卡掉。。。
正解:可持久化左偏樹+堆維護可能集合
原**:
概括:結論:
1.t為根求最短路樹t,定義p'為路徑s-t的路徑p和t沒有交集的部分,p』和p都是有序邊集
對於p'中相鄰邊一定存在tail和head的祖先後代關係(或者重合)
2.新定義邊的代價:dis[v]+w-dis[u],即換邊走的額外可能花費
這樣乙個p就是:dis[1~n]+∑e∈p' newweight[e]
3.p和p'一一對應。
求法:1.t為根求最短路樹
2.非樹邊放進u的左偏樹內,
3.dfs可持久化合併堆,得到到根路徑上的出邊的堆
4.堆維護四元組(u,v,pos,val)邊集倒數第二條邊tail是u,倒數第一條邊tail是v,v的這個邊的左偏樹節點編號pos,p』的代價val
更新:a.v找到rt[v]最小的加入p的末尾
b.u找到rt[u]下乙個最小的邊作為新的v和pos,這個邊一定是pos的左兒子或者右兒子
初始:(0,1,*,0)要特判
注意特判:
a.rt[v]=0?
b.pos沒有左右兒子?
#include#define reg register int#define il inline
#define fi first
#define se second
#define mk(a,b) make_pair(a,b)
#define numb (ch^'0')
#define pb push_back
#define solid const auto &
#define enter cout<#define pii pairusing
namespace
std;
typedef
long
long
ll;template
il void rd(t &x)
template
il void output(t x)
template
il void ot(t x)
template
il void prt(t a,int st,int nd)
namespace
miraclee[m];
int hd[n],cnt=0
;void add(int x,int y,double
z)struct
edgeb[m];
double
dis[n];
struct
po po(
int xx,double
vv)
bool friend operator
<(po a,po b)
};priority_queue
q;bool
vis[n];
intpre[n];
void
dij()}}
}bool
on[m];
struct
tr tr(
double v,int
ddd)
}t[m*20
];int
tot;
intrt[n];
int merge(int x,int y,int
typ)
t[x].rs=merge(t[x].rs,y,typ);
if(t[t[x].ls].dt[x].d=t[t[x].rs].d+1
;
returnx;}
struct
sol sol(
int uu,int vv,int pp,double
vd)
bool friend operator
<(sol a,sol b)
};void dfs(intx)}
priority_queue
hp;int
main()
dij();
//for(reg i=1;i<=n;++i)
memset(hd,0,sizeof
hd);
cnt=0
;
for(reg i=1;ii)
for(reg i=1;i<=m;++i)
}dfs(n);
hp.push(sol(
0,1,-233,0
));
double st=dis[1
]; ll ans=0
;
while(!hp.empty())
}else
if(t[now.pos].ls)
if(t[now.pos].rs)}}
ot(ans);
return0;
}}signed main()
/*author: *miracle*
*/
K短路 學習筆記
k短路,顧名思義,是讓你求從 s 到 t 的第 k 短的路。暴力當然不可取,那麼我們有什麼演算法可以解決這個問題?首先,我們要維護乙個堆。struct node priority queue q 這個堆是用來幹什麼的?這時候要提到一種新演算法 a 演算法。估價函式 f i g i h i 其中,g ...
筆記 K短路
一.定義 從起點 出發到達目標 的第 小的路徑 二.樸素演算法 直接bfs 帶優先佇列 當目標節點 第 次出佇列時,即為所求 解釋 bfs第一次搜到 點時,即為最短距離,那麼當第二次搜到呢?不用說,是次短路 rt.次短路 節點 距離 1 6 出佇列 佇列內元素 1 0 2 7 3 9 6 14 2 ...
更新 學習筆記 凸包 K短路
這週cyc的套題裡出現了兩個新的演算法,乙個是計算幾何之凸包,還有乙個是最短路擴充套件之k短路,在此做乙個 凸包專題 那麼構建凸包之後我們相當於用最短的長度將平面內所有的點包圍起來 兩點之間線段最短 對於乙個凸包,我們從它的原點 即圖中紅點 向點集中的中間點 圖中點6 連一根線,會將凸包分成兩個凸狀...