1 流程
dist[所有点] = INF
dist[起始点] = 0
队列
起始点入队并标记
while(队列不空)
{
取出队头t
st[t] = false // spfa的st代表节点是否在队列中 dij的代表是否走过
用t更新其他所有出点(入队/标记)
}
判断是否能走
2 code
int spfa( int u )
{
//memset( cnt, 0, sizeof cnt );
memset( dist, INF, sizeof dist );
dist[u] = 0;
queue< int > q;
q.push( u );
st[u] = true;
// for(int i=1;i<=n;i++)
// {
// st[i]=true;
// q.push(i);
// }
while( q.size() )
{
int t = q.front();
q.pop();
st[t] = false;
for( int i = h[t]; i; i = ne[i] )
{
int y = e[i], z = w[i];
if( dist[y] > dist[t] + z )
{
dist[y] = dist[t] + z;
// cnt[y]=cnt[t]+1;
// if(cnt[y]>=n)
// 有负环
if( !st[y] )
{
q.push( y );
st[y] = true;
}
}
}
}
if( dist[n] > 0x3f3f3f3f /2 )
return -1;
else
return dist[n];
}
3 spfa判断负环
cnt[]代表到达当前点最短路的边数
如果cnt[x] >= n ,说明至少经过n
条边即n + 1个点, 则至少有一个点
重复
cnt[所有点] = 0
初始时所有点入队
最短距更新时cnt也更新
判断是否 > n