关于我写了一年堆优化的\(SPFA\)这件事
今天我研究为啥\(dij\)不能跑负边权这件事的时候
我的没有每个点只能进队一次的限制,然后我认为堆优化的\(dij\)也是可以跑负边的
于是乎我就懵逼了
后来发现堆优化的\(dij\)每个点只能进队一次,标上\(vis\),只能进一次,也就是说必须保证当前点是距离最小的点
但是有负边权的话,就不能保证是距离最小的点了
于是乎我写的那个可以重复进队,于是是个四不像算法
怪不得我之前分析我自己的最短路复杂度的时候,总感觉多个常数
发现我的最短路,不仅可以重复进队,还没有\(vis\),战神叫它堆优化的\(SPFA\)
记住,\(dij\)每个点只能进队一次保证复杂度,\(SPFA\)每个点在队里就不用新加了
下面放上我的堆优化的\(SPFA\)
code
int dis[N];
struct node{
int x,d;
node(){}
node(int a,int b){x=a;d=b;}
bool operator < (node a)const{
return d>a.d;
}
};
priority_queue<node> q;
void dij(){
memset(dis,0x3f,sizeof(dis));
dis[1]=0;q.push(node(1,0));
while(!q.empty()){
int x=q.top().x;q.pop();
for(int i=head[x];i;i=nxt[i]){
int y=to[i];
// cout<<endl<<"SB"<<" "<<x<<" "<<dis[x]<<" "<<len[i]<<" "<<y<<" "<<dis[y]<<endl;
if(dis[y]<=dis[x]+len[i])continue;
dis[y]=dis[x]+len[i];
q.push(node(y,dis[y]));
}
}
}