朴素
O(nm)
int k;//边数限制
int dist[N], back[N];
struct Edge
{
int a, b, w;
} e[M];
void bellman_ford(int start)
{
memset(dist, 0x3f, sizeof(dist));
dist[start] = 0;
for (int i = 0; i < k; i++)
{
memcpy(back, dist, sizeof(back));//无边数限制可删除
for (int j = 0; j < m; j++)
{
int a = e[j].a, b = e[j].b, w = e[j].w;
dist[b] = min(dist[b], back[a] + w);//无边数限制:dist[b] = min(dist[b], dist[a] + w);
}
}
}
队列优化版
O(m),可能被卡到O(nm)
int h[N], w[M], e[M], ne[M], idx;//memset(h, -1, sizeof h);
int dist[N];
bool st[N];
void add(int a, int b, int c)
{
e[idx] = b;
ne[idx] = h[a];
w[idx] = c;
h[a] = idx++;
}
void spfa(int start)
{
queue<int>q;
memset(dist,0x3f,sizeof dist);
dist[start]=0;
q.push(start);
st[start]=1;
while(q.size())
{
int t=q.front();
q.pop();
st[t]=0;
for(int i=h[t];i!=-1;i=ne[i])
{
int j=e[i];
if(dist[j]>dist[t]+w[i])
{
dist[j]=dist[t]+w[i];
if(!st[j])
{
q.push(j);
st[j]=1;
}
}
}
}
}
spfa(SLF优化)
int h[N], w[M], e[M], ne[M], idx; //memset(h, -1, sizeof h);
int dist[N];
bool st[N];
void add(int a, int b, int c)
{
e[idx] = b;
ne[idx] = h[a];
w[idx] = c;
h[a] = idx++;
}
void spfa(int start)
{
deque<int> q;
memset(dist, 0x3f, sizeof dist);
dist[start] = 0;
q.push_back(start);
st[start] = 1;
while (q.size())
{
int t = q.front();
q.pop_front();
st[t] = 0;
for (int i = h[t]; i != -1; i = ne[i])
{
int j = e[i];
if (dist[j] > dist[t] + w[i])
{
dist[j] = dist[t] + w[i];
if (!st[j])
{
st[j] = 1;
if (q.size() && dist[j] < dist[q.front()])
{
q.push_front(j);
}
else
{
q.push_back(j);
}
}
}
}
}
}