最短路
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]});
}
}
}
}

浙公网安备 33010602011771号