最短路

Floyd

复杂度\(O(n^3)\)

可以求解多源最短路

本质上是dp

f[i][j] 表示从 \(i\) 点到 \(j\) 点只允许经过前 \(k\) 号点的最短路

for(int k=1;k<=n;k++)
    for(int i=1;i<=n;i++)
    	for(int j=1;j<=n;j++)
        	if(dis[i][j]>dis[i][k]+w[k][j])
                dis[i][j]=dis[i][k]+w[k][j];

据说 \(k\ i\ j\) 顺序打错了多跑几遍也可以得到正确的结果

SPFA

是Bellman-Ford的队列优化 复杂度\(O(ke)\) 可以被构造的数据卡至$O(nm) $ 但是在一条链上跑的飞快

可以用来求带负权但没有负环的最短路

void spfa(int start)
{
    queue<int> q;
    q.push(start);
    dis[start]=0;
    while(!q.empty())
    {
        int u=q.front();
        q.pop();
        vis[u]=0;
        for(int i=head[u];i;i=edge[i].next)
        {
            int v=edge[i].to;
            if(dis[v]>dis[u]+edge[i].dis)
            {
                dis[v]=dis[u]+edge[i].dis;
                if(!vis[v])
                {
                    vis[v]=1;
                    q.push(v);
                }    
            }
        }
    }
}

优化???

SLF

设将要插入的元素 \(j\) 和现在的队首元素 \(i\)

dis[j]<dis[i]则将 \(j\) 插入队首

否则插入队尾

关于SPFA:

dijkstra

无法求解带负权图

复杂度\(O(m \log n)\)

struct node
{
    int u,dis;
    bool operator < (const node &x)const
    {
        return x.dis<dis;
    }
};

void dijkstra(int start)
{
    memset(dis,0x3f,sizeof(dis)); //INF=f[0]
    priority_queue<node> q;
    dis[start]=0;
    q.push{(node){start,0}};
 	while(!q.empty())
    {
        int now=q.top().u;
        q.pop();
        if(vis[now])
            continue;
        vis[now]=1;
        for(int i=head[now];i;i=edge[i].next)
        {
            int v=edge[i].to;
            if(dis[v]>dis[now]+edge[i].dis)
            {
                dis[v]=dis[now]+edge[i].dis;
                if(!vis[v])
                    q.push((node){v,dis[v]});
            }
        }
    }
}
posted @ 2019-10-15 21:38  nenT  阅读(100)  评论(0)    收藏  举报