SPFA算法:
Dijkstra算法的改进版,整体思想同Dijkstra算法一致。
1、保存一个带权有向图
使用链式前向星保存一个有向图
class Edge
{
public:
int to;
int weight;
int next;
};
Edge e[maxn << 1];
void InsertEdge(int u, int v, int w)
{
e[++cnt].to = v;
e[cnt].next = head[u];
e[cnt].weight = w;
head[u] = cnt;
}
void CreateGraph()
{
int u, v, w;
cout << "请输入结点数:" << endl;
cin >> n;
cout << "请输入边数:" << endl;
cin >> m;
cout << "请依次输入每条边边的两个顶点和权值:" << endl;
for (int i = 1; i <= m; i++)
{
cin >> u >> v >> w;
InsertEdge(u, v, w);
}
}
2、初始化
建立队列用于存放结点号,选择一个结点为源点,将其距离初始化并入队;
建立一个访问标记数组用于确定结点是否在队列中;建立距离数组,存放结点的最短路径。
queue<int>q;
memset(vis, false, sizeof(vis));
memset(dis, 0x3f, sizeof(dis));
vis[u] = 1;
dis[u] = 0;
q.push(u);
3、执行算法
取走队头元素并解除标记,遍历其邻接点,更新最小距离后,若邻接点不在队列中,将其标记并入队;
循环执行,直到队列为空。
while (!q.empty())
{
int x = q.front();
q.pop();
vis[x] = 0;
for (int i = head[x]; i; i = e[i].next)
{
int v = e[i].to;
if (dis[v] > dis[x] + e[i].weight)
{
dis[v] = dis[x] + e[i].weight;
if (vis[v])
{
continue;
}
vis[v] = true;
q.push(v);
}
}
}
整体代码实现:
#include<iostream>
#include<queue>
using namespace std;
#define maxn 100
int n, m, cnt;
int head[maxn], dis[maxn];
bool vis[maxn];//标记是否在队列中
class Edge
{
public:
int to;
int weight;
int next;
};
Edge e[maxn << 1];
void InsertEdge(int u, int v, int w)
{
e[++cnt].to = v;
e[cnt].next = head[u];
e[cnt].weight = w;
head[u] = cnt;
}
void CreateGraph()
{
int u, v, w;
cout << "请输入结点数:" << endl;
cin >> n;
cout << "请输入边数:" << endl;
cin >> m;
cout << "请依次输入每条边边的两个顶点和权值:" << endl;
for (int i = 1; i <= m; i++)
{
cin >> u >> v >> w;
InsertEdge(u, v, w);
}
}
void SPFA(int u)
{
queue<int>q;
memset(vis, false, sizeof(vis));
memset(dis, 0x3f, sizeof(dis));
vis[u] = 1;
dis[u] = 0;
q.push(u);
while (!q.empty())
{
int x = q.front();
q.pop();
vis[x] = 0;
for (int i = head[x]; i; i = e[i].next)
{
int v = e[i].to;
if (dis[v] > dis[x] + e[i].weight)
{
dis[v] = dis[x] + e[i].weight;
if (vis[v])
{
continue;
}
vis[v] = true;
q.push(v);
}
}
}
}
void Print()
{
for (int i = 1; i <= n; i++)
{
cout << dis[i] << " ";
}
cout << endl;
}
int main()
{
CreateGraph();
SPFA(1);
Print();
return 0;
}