SPFA是可以优化的,这个大家都是晓得的吧。
下面介绍两种SPFA的神奇优化(我只代码实现了的一种)
SLF:Small Label First策略,设要加入的节点是j,队首元素为i,若dist(j) < dist(i),则将j插入队首,否则插入队尾。
LLL:Large Label Last策略,设队首元素为i,每次弹出时进行判断,队列中所有dist值的平均值为x,若dist(i)>x则将i插入到队尾,查找下一元素,直到找到某一i使得dist(i)<=x,将i出对进行松弛操作。
至于证明。。。我也不会
下面附上的我的SLF优化代码
int spfa(int a,int b) { memset(dist,inf,sizeof(dist)); memset(can,0,sizeof(can)); memset(vis,0,sizeof(vis)); deque <int> q; for (ri i=1;i<=m;i++) for (ri j=a;j<=b;j++) if (cut[i][j]) can[i]=1; q.push_back(1); dist[1]=0; vis[1]=1; while (!q.empty()) { int k=q.front();q.pop_front();vis[k]=0; for (ri i=head[k];i;i=edge[i].next) { int v=edge[i].to; if (!can[v]&&dist[v]>dist[k]+edge[i].c) { dist[v]=dist[k]+edge[i].c; if (!vis[v]) { int f=q.front(); if (dist[v]<dist[f]) q.push_front(v); else q.push_back(v); vis[v]=1; } } } } return dist[m]; }
使用双端队列deque实现,说实话我用STL有种优化了和没优化一样的感觉