spfa的关键: 只有上一次经过松弛操作的点,才可能使其邻接点的距离值产生改变
用一个队列来存放被成功松弛的顶点。初始时,源点s入队。当队列不为空时,取出队首顶点,对它的邻接点进行松弛。如果某个邻接点松弛成功,且该邻接点不在队列中,则将其入队。经过有限次的松弛操作后,队列将为空,算法结束。
#include <iostream>
#include <queue>
#include <vector>
#define Max 10000
#define Maxe 10000 //最大边数
#define Maxn 1000 //最大点数
using namespace std;
struct edge
{
int to,w,next;
}edge[Maxe];
int c[num_v],vis[num_v],d[num_v],head[Maxn]; //计数器·标记·最短路长
void init()
{
memset(c,0,sizeof(c));
memset(vis,0,sizeof(vis));
memset(d,0x3f,sizeof(d));
memset(head, -1 ,sizeof(head));
}
bool spfa(int s) //s为起始点
{
queue<int>q;
d[s] = 0;
q.push(s);
vis[s] = 1;
while(!q.empty())
{
int temp;
temp = q.front(); vis[temp] = 0; q.pop();
c[s]++;
if(c[s] > n)
{
return false;
}
for(int k = head[temp]; k != -1; k = edge[k].next)
{
if(d[edge[k].to] > d[temp] + edge[k].w)
{
d[edge[k].to] = d[temp] + edge[k].w;
if(!vis[edge.to])
{
vis[edge.to] = 1;
q.push(edge.to);
}
}
}
return true;
}
}