Dijkstra堆优化的写法讨论
WorldBest丶牛顿 · · 题解
本题解较适合堆优化重载括号运算符的同学看
众所周知,
一种常见的优化,就是优先队列(堆)优化
优先队列的写法对每个人来说也是各不相同
针对一种重载括号运算符的写法,我想谈一谈我的看法
代码:
struct cmp{
bool operator()(const int &x,const int &y)
const
{
return dis[x]>dis[y];
}
};
priority_queue<int,vector<int>,cmp>q;
void dijkstra(){
int u,v,w;
for(int i=1;i<=n;++i) d[i]=2147483647;
dis[s]=0;q.push(s);
while(!q.empty()){
u=q.top();
q.pop();
if(vis[u]) continue;
vis[u]=true;
for(int i=head[u];i;i=p[i].nxt){
v=p[i].to;w=p[i].w;
if(dis[u]+w<dis[v])
{
dis[v]=dis[u]+w;
q.push(v);
}
}
}
}
这种写法保留了
并且这种写法在某本著名的书中也出现了
但是这种方法真的没有问题吗?
我们可以考虑,如果在更新其他节点的时候,某一个节点被多次更新,那么它每次的
那么如果一个节点更新的次数足够多时,它总有一次会跟自己进行比较,那么它会因为自己与自己的
那么它就会在堆中形成一种类似于“路障”的东西将堆的某些部分“堵住”
而这种写法在数据结构上也破坏了堆原有的性质,就会使算法出现错误
如下图: