最短路径问题(一)

Dijkstra算法

适用于边权为正的情况下,有向图与无向图均适用

用途:

计算正权图上的单源最短路(Single-Source Shortest Paths,SSSP)

步骤:

1>.  初使时令 S={V0},T={其余顶点},T中顶点对应的距离值,若存在<V0,Vi>,为<V0,Vi>弧上的权值(和SPFA初始化方式不同),若不存在<V0,Vi>,为Inf。

2>.  从T中选取一个其距离值为最小的顶点W(贪心体现在此处),加入S(注意不是直接从S集合中选取,理解这个对于理解vis数组的作用至关重要),对T中顶点的距离值进行修改:若加进W作中间顶点,从V0到Vi的距离值比不加W的路径要短,则修改此距离上面两个并列for循环,使用最小点更新)。


伪代码:

(1)清除所有点的标号

(2)设d[0]=0,其他d[i]=INF

(3)循环n次

   {

        在所有未标号的节点中,选出d值最小的节点x

        给结点x标记

        对于从x出发的所有边(x,y),更新d[y]=min{ d[y],d[x]+w(x,y) }

}

//假设起点是结点0,它到结点i的路径长度为d[i],未标号的结点的v[i]=0,已标号的结点的v[i]=1.用w[x][y]==INF表示边(x,y)不存在
//Dijkstra算法
memset(v, 0, sizeof(v));
for(int i = 0; i < n; i++)
d[i] = (i == 0 ? 0 :INF);
for(int i = 0; i < n; i++)
{
	int x,m =INF;
	for (int y = 0; y < n; y++)
	if(!v[y] && d[y]<=m) m = d[x=y];
v[x]=1;
for(int y = 0; y < n; y++) 
	d[y] = min(d[y], d[x] + w[x][y]);
}

松弛操作:(relaxation)

松弛操作就是让顶点与顶点之间的路径变短的操作,就像一根橡皮筋连接x和y两点,现在有一点v到y的路径更短,现在把橡皮筋y点的另一端x换成v点,这样缓解橡皮筋紧绷的压力,让其变得松弛。

下面的代码是边(x,y)上的松弛操作

//松弛操作
if (d[y] > d[x] +w[x][y])
{
	d[y] = d[x] + w[x][y];
	fa[y] = x;
}

时间复杂度:O(n^2)

 解析: 循环体一共执行了n次,在每次循环中“求最小d值”与“更新其他d值”的时间复杂度均为O(n)

算法优化:

该算法可以采用邻接表的方法将算法时间复杂度变为O(mlogn)

其中最坏的情况是m与n^2同阶,此时算法为负优化。

m与n^2有以下两种关系:

(1)m远小于n^2  称为稀疏图(Sparse Graph) 适合使用vector数组保存。

(2)m大于n^2   称为稠密图(Dense Graph) 适合使用邻接表(Adjacency List)保存。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值