const int INF = 999999;
int map[MAXN][MAXN]; //map[i,j]为初始输入的i到j的距离,未知的map[i,j]=INF;
int dis[MAXN];//源点S到i的最短路
char vst[MAXN];//是否在队列中的标记
int Q[MAXN];//队列
// 参数n表示结点数,s表示源点
int SPFA(int n, int s)
{ int i, pri, end, p, t; // pri是队列头结点,end是队列尾结点
memset(vst, 0, sizeof(vst));//初始化
for(int i=0; i<</b>MAXN; ++i)
Q[i] = 0;//初始化队列为空
for (i=0; i<</b>n; i++)
dis[i] = INF;//初始化源点到I的值为最大值
dis[s] = 0;//源点为0
vst[s] = 1;//标记为已入队
Q[0] = s;//源点入队
pri = 0; end = 1;//队首队尾赋值
while (pri <</b> end)
{
p = Q[pri];//取队首元素
for (i=0; i<</b>n; ++i) //更新dis
{ if (dis[p]+map[p][i] <</b> dis[i])
{ dis[i] = dis[p]+map[p][i];
if (!vst[i]) //未在队列中
{ Q[end++] = i;
vst[i] = 1;
}
}
}
vst[p] = 0; // 置出队的点为未标记
pri++;
}
return 1;
}
标程二:
int num[999999]; //记录入队次数
void spfa(int s) // 初始结点s,即为起点,若目标结点t,则输出dict[t]。
{ init_data(s);
int head = 0, tail = 1;
int path[Max]; // 可增加一个path[]数组来记录最后s到t的路径。
queue[0] = s; //que.push(s);
dict[s] = 0;
while (tail > head)//(!que.empty())
{ int u = queue[head];//int u=que.front(); //que.pop();
vis[u] = true;
for (i = 1; i <= n; i ++)
{ if (dict[i] > dict[u] + edge[u][i])
{ dict[i] = dict[u] + edge[u][i];
path[i] = u;
num[i]++
if(num[i]>=n) return 1;//判断是否有负权值……
if (!vis[i]) // 对以前没有访问过的顶点,加入队列中。
{ vis[i] = true;
queue[tail] = i;// que.push(i);
tail ++;
}
}
}
vis[u] = false; // 记得把出队列的顶点的vis[]置为false。
head ++;
}
}
判断负权回路 num[i]>=n的原因,即使所有的点更新都会让i入队的话,才只有n-1次,这时一定是最小值了,入队n次,一定有负权回路