spfa判负环
cpp
int spfa()
{
//初始化所有非起点和起点的距离
// memset(dist, 0x3f, sizeof dist);
// dist[1] = 0;
// 这里不需要初始化dist数组为 正无穷。不用初始化的原因是, 如果存在负环, 那么dist不管初始化为多少, 都会被更新
//定义队列,起点进队, 标记进队
queue<int> q;
for (int i = 1; i <= n; i ++ )
{
//判断负环,只从一个点出发,有可能到达不了负环那里,需要一开始就把所有结点放入队列,且标记进入了队列降低效率
q.push(i);
st[i] = true;
}
//队列中的点用来更新其他点到起点的距离
while (q.size())
{
//取队头,弹队头
auto t = q.front();
q.pop();
//t出队,标记出队
st[t] = false;
//更新与t邻接的边
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];//结点j可以通过中间点t降低距离
cnt[j] = cnt[t] + 1;//那么结点j在中间点t的基础上加一条到自己的边
if (cnt[j] >= n) return true;//边数不小于结点数,出现负环,函数结束
if (!st[j])//若此时j没在队列中,则进队。已经在队列中了,上面已经更新了数值。重复加入队列降低效率
{
//j进队,标记进队
q.push(j);
st[j] = true;
}
}
}
}
return false;//走到这了,函数还没结束,意味着边数一直小于结点数,不存在负环
}