【模板】最短路算法的优化

来源:互联网 发布:网络机房日常维护项目 编辑:程序博客网 时间:2024/06/05 17:13

SPFA__SLF
SPFA在进行松弛操作的时候 肯定存在解使得答案更差 那么我们可以后考虑它们
这样就可以用双端队列来维护了

代码:

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<queue>using namespace std;const int maxn = 233333;const int inf = 2147483647;int tot;int first[maxn],nxt[maxn],d[maxn];struct edge{    int from,to,cost;}es[maxn];void init(){    memset(first,-1,sizeof(first));    tot=0;}void build(int ff,int tt,int dd){    es[++tot]=(edge){ff,tt,dd};    nxt[tot]=first[ff];    first[ff]=tot;}bool vis[maxn];deque<int>q;void spfa(int s){    d[s]=0;    vis[s]=1;    q.push_front(s);    while(!q.empty())    {        int u=q.front();        q.pop_front();        vis[u]=0;        for(int i=first[u];i!=-1;i=nxt[i])        {            int v=es[i].to;            if(d[v]>d[u]+es[i].cost)            {                d[v]=d[u]+es[i].cost;                if(!vis[v])                {                    vis[v]=1;                    if(q.empty())                        q.push_front(v);                    else if(d[v]>d[q.front()])                        q.push_back(v);                    else                        q.push_front(v);                }            }        }    }}

堆优化dijkstra优先队列实现
C++内置的STL 函数优先队列 本质上是一个大根堆 首先我们需要进行重载操作
为什么是可行的呢???
因为dijkstra每次更新的时候,在没有负权的情况下,我们当前最小的答案一定是最优的,那么我们记录一下当前点的编号以及它现在的权值之和,压入一个小根堆,那么我们访问的时候就会优先访问答案更优的呢 时间复杂度也优化成了nlogn呢

代码:

#include<iostream>#include<cstdio>#include<cstring>#include<queue>#include<algorithm>using namespace std;const int maxn = 23333;int t,c,ts,te,first[maxn],next[maxn],d[maxn],tot;bool vis[maxn];struct edge{    int from,to,cost;}es[maxn];struct point{    int num,v;};bool operator < (point a,point b){    return a.v > b.v;}void build(int ff,int tt,int dd){    es[++tot] = (edge){ff,tt,dd};    next[tot] = first[ff];    first[ff] = tot;}priority_queue<point>q;void dij_heap(int s){    d[s] = 0;    q.push((point){s,0});    while(!q.empty())    {        point now = q.top();        q.pop();        int u = now.num;        vis[u] = 1;        for(int i = first[u];i != -1;i = next[i])        {            int v = es[i].to ;            if(d[v] > d[u] + es[i].cost)            {                d[v] = d[u] + es[i].cost;                q.push((point){v,d[v]});            }        }    }}
0 0