您的位置:首页 > 其它

最短路算法(Dijkstra、Bellman-Ford、SPFA邻接表实现)

2019-04-14 00:42 337 查看

最短路算法的邻接矩阵实现
邻接矩阵实现起来比较简单,但对空间的利用效率不高,常常会导致内存超限的MLE,此时就应当改用邻接表实现,省去不必要的边,减小内存消耗

邻接表的构造

邻接表都是利用Vector替换原来的map数组实现的。由于邻接表的本质是存储边,所以我们还要定义一个结构体,包含两个值,一个是这条路的终点,一个是这条路的长度。开一个向量数组,一个点一个向量,每次都把与那个点相关的点加如向量

struct info
{
int to, dist;
};

vector<info> map[maxn];

Dijkstra的邻接表实现

Dij算法的邻接表和邻接矩阵相比,差异只在于更新各点到起点的距离。由于是邻接表,所以那个循环枚举的是边,而不是想邻接矩阵那样枚举点,就不必想邻接矩阵那样判断是否存在边。将x点的向量map[x]从头枚举到尾,每一个元素的to值就是可以到的终点,dist值就是距离

int dist[maxn], vis[maxn];

void dijkstra(int start, int n)
{
memset(vis, 0, sizeof(vis));
fill(dist, dist + n + 1, INF);
dist[start] = 0;
for(int i = 0; i < n; i++)
{
int mini = INF, x;
for(int j = 0; j < n; j++)
{
if(dist[j] < mini && !vis[j])
{
mini = dist[j];
x = j;
}
}
vis[j] = 1;

//以下才开始变化
for(int j = 0; j < map[x].size(); j++) //枚举map[x]里的所有元素
{
if(dist[map[x][j].to] < dist[x] + map[x][j].dist)
{
dist[map[x][j].to] = dist[x] + map[x][j].dist;
}
}
}
}

Bellman-Ford算法的邻接表实现

和Dij一样

void bellmanFord(int start, int n)
{
bool flag = false;
for(int k = 0; k < n - 1 && !flag; k++)
{
flag = true;
for(int i = 0; i < n; i++)
{
for(int j = 0; j < map[i].size(); j++)
{
if(dist[map[i][j].to] < dist[i] + map[i][j].dist)
{
flag = true;
dist[map[i][j].to] = dist[i] + map[i][j].dist;
}
}
}
}
}

bool negLoop(int n)
{
for(int i = 0; i < n; i++)
{
for(int j = 0; j < map[i].size(); j++)
{
if(dist[map[i][j].to] < dist[i] + map[i][j].dist)
{
return false;
}
}
}
return true;
}

SPFA

bool SPFA(int start, int n)
{
que.push(start);
dist[start] = 0;
vis[start] = enqueue_num[start] = 1;
int x;
while(!que.empty())
{
x = que.front();
que.pop();
vis[x] = 0;
if(enqueue_num[x] > n)
{
return false;
}
for(int j = 0; j < mp[x].size(); j++)
{
int i = mp[x][j].to;
if(dist[x] + mp[x][j].dist < dist[i])
{
dist[i] = dist[x] + mp[x][j].dist;
if(!vis[i])
{
que.push(i);
vis[i] = 1;
enqueue_num[i]++;
}
}
}
}
return true;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐