您的位置:首页 > 其它

最短路经问题

2012-09-12 09:41 148 查看

Prim算法:

主要处理问题:最小生成树问题。

算法思想:V表示所有节点集合,首先s进入集合U,然后找出集合U与剩余节点V-U中最小权值的边[u,v],将v加入集合U,直到U==V截至

时间复杂度:相对与Kruskal需要多次排序,>>O(E)

Kruskal算法:推荐

主要处理问题:最小生成树问题。

算法思想:对所有边按照权值进行排序,然后使用并查集,将所有节点加入到集合中。

时间复杂度:O(E)

Dijkstra算法:推荐

主要处理问题:权值为正,单源点最短路径问题

算法思想:N-1次松弛,每次找出没有被访问过d值最小的节点x,然后对所有与x相连的节点进行松弛

时间复杂度:O(N*N),比较稳定

Bellman_Ford算法:

主要处理问题:权值为负,无负环,单源点最短路径问题

算法思想:N-1次松弛,每次历遍完所有边进行松弛

时间复杂度:O(N*E)

SPFA算法:推荐

(Shortest Path Faster Algorithm)

主要处理问题:权值为负,无负环,单源点最短路径问题。或者稀疏图,邻接表实现

算法思想:bfs+松弛,队实现,首先s入队,输出队首元素u,然后历遍与u相连的所有边[u,v],然后进行松弛,如果松弛成功,并且v没有在队中,则将v入队。

时间复杂度:O(E) --- O(N*E),不稳定

拓展:如果某一个节点入队超过N-1次,则存在负环

Floyd算法:

主要处理问题:所有节点间最短路径问题
算法思想:动态规划,三重循环
时间复杂度:O(N^3)

算法模板:

//Dijkstra
int dijkstra(int s, int e)
{
for(i = 0; i < N; ++ i) d[i] = INF;
d[s] = 0;
memset(vis, 0, sizeof(vis));
for(i = 0; i < N - 1; ++ i)
{
int x = 0;
for(j = 0; j <= N; ++ j) if(!vis[j] && d[j] < d[x])
x = j;
vis[x] = 1;
for(j = 0; j <= N; ++ j) if(map[x][j] && d[j] > d[x] + map[x][j])
d[j] = d[x] + map[x][j];
}
return d[e];
}

//SPFA
struct Node
{
int v, w;
};
vector<Node> G[nMax];
int vis[nMax];
int spfa(int s, int e)
{
memset(vis, 0, sizeof(vis));
for(i = 0; i < N; ++ i) dis[i] = INF;
dis[s] = 0;
queue<int> que;
que.push(s);
while(!que.empty())
{
int u = que.front();
que.pop();
vis[u] = 0;
for(i = 0; i < G[u].size(); ++ i)
{
Node tmp = G[u][i];
if(dis[tmp.y] > dis[u] + tmp.w)
{
dis[tmp.y] = dis[u] + tmp.w;
if(!vis[tmp.y])
{
vis[tmp.y] = 1;
que.push(tmp.y);
}
}
}
}
return dis[e];
}

//Floyd
for(k = 0; k < N; ++ k)
for(i = 0; i < N; ++ i)
for(j = 0; j < N; ++ j)
if(d[i][j] > d[i][k] + d[k][j])
d[i][j] = d[i][k] + d[k][j];


推荐博客:http://blog.csdn.net/v_JULY_v/article/details/6181485
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: