废话不多说,直接来代码
//spfa 邻接表
使用邻接表求最短路径 复杂度降低至O(M) 在对于做稀疏矩阵的题目的时候 能有更好的效果
在网上也看了不少的邻接表的存储图 但是一直以来总是不是很明白 然后自己琢磨了琢磨 ,希望 我自己的语言可以给其他人带来更好的理解
head[MAX] 数组 head[i] 表示的是 以i为起点的边在 edg[MAX] 数组中的位置
next[MAX] 数组 next[i] 表示的是 以head[i] 为起点的上一条以i(注意 此处是在head中的i)为起点的 在edg[MAX]的位置
并且next后可能还存在有i的边 那么这些边放next中 所以我们在检查的时候1.看以next[i]为下标的next[next[i]]是不是等于-1,如果不是 那么表示还有一条以i(注意是在head中的i) 为起点的边
如果是-1 我们不管 就可以了 因为我们把head 初值赋值为-1 就可以啦
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define inf 9999999
#define MAX 500
int dis[MAX], head[MAX], vis[MAX], cnt[MAX];
struct edg
{
int from, to, w, next;
}e[MAX];
int n, m, t;
void add(int x, int y, int w)
{
t++;
e[t].from = x;
e[t].to = y;
e[t].w = w;
e[t].next = head[x];
head[x] = t;
}
void spfa(int k)
{
//先初始化dis
for (int i = 1; i <= n; i++)
{
dis[i] = inf;
vis[i] = 0;
}
dis[k] = 0;
vis[k] = 1;
queue<int> q;
q.push(k);
while (!q.empty())
{
int u = q.front();
q.pop();
vis[u] = 0;
for (int i = head[u]; i != -1; i = e[i].next) {
int v = e[i].to;
if (dis[v] > dis[u] + e[i].w) {
dis[v] = dis[u] + e[i].w;
if (!vis[v])
{
vis[v] = 1;
q.push(v);
}
}
}
}
}
int main()
{
int k;
cin >> k;
while (k--)
{
t = 0;
memset(head, -1, sizeof(head));
memset(e, 0, sizeof(e));
cin >> n >> m;
for (int i = 1; i <= m; i++) {
int x, y, v;
cin >> x >> y >> v;
add(x, y, v);
}
spfa(1);
//system("pause");
return 0;
}