dirkstra:
步骤:
每次找到一个点得到这个点到源点的最短距离,再从标记中的点找到距离源点最短距离的点然后在修改它的距离源点的距离值,最后得到所有点到源点的距离。
下面代码示例
def dijkstra(graph, start):
vertices, verticesIndex = [{'index': i, 'weight': None} for i in range(graph.number)], [i for i in range(graph.number)]
vertices[start - 1]['weight'] = 0
heapSort(vertices, verticesIndex)
while len(vertices) > 0:
swapVertices(vertices, verticesIndex, 0, -1)
vertex = vertices.pop()
transformToHeap(vertices, verticesIndex, 0, len(vertices))
updateDistance(graph, vertices, verticesIndex, vertex)
也是一次新的dijkstra算法理解
Floyd算法:
用动态规划算法简单粗暴地解决问题dp[i][j][k] 表示从i到j的路径里只能选择1到k的节点的最短路径
状态转移:dp[i][j][k]=min(dp[i][k][k-1]+dp[k][j][k-1] , dp[i][j][k-1])
其中第一个表示经过了节点k 第二个表示不仅过节点k、
因为k是递增的,第三维在数组中一直是k-1出现。所以我们在三重循环下做二维数组就能解决
代码示例如下:
for(k=1;k<=n;k++)
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(e[i][j]>e[i][k]+e[k][j] )
e[i][j]=e[i][k]+e[k][j];
SPFA算法:
带负权边的图适用此种算法,可以先判断是否存在负环,若存在则无法计算最短路
首先建立队列列中起始只有源点,在建立一个表格用于记录n个点到源点的最短路径,初始值设为INF,把队列中的点作为源点计算所有点的最短路,计算刷新完毕后将点放入队列最后,一直到队列空
代码示例:
void spfa(s);
for i=1 to n
do { dis[i]=INF; vis[i]=false; }
dis[s]=0;
vis[s]=true; //源点s入队列
head=0;
tail=1;
q[tail]=s;
while head<tail
do {
head+1; //队首出队
v=q[head];
vis[v]=false;
for 每条边(v,i)
if (dis[i]>dis[v]+a[v][i])
dis[i] = dis[v] + a[v][i]
if (vis[i]=false)
{tail+1; q[tail]=i; vis[i]=true;} //如果不在队列,则加入队列
}
简单的复习了一下最小生成树和最短路,还没怎么刷题巩固