先介绍用邻接表存储一个图
用city表示图中点的个数,road表示点之间的连线
1.存储:
用u[ ],v[ ],w[ ]数组存储road的起点,终点,边的权值,一般定义的大小略大于city的最大值
用first[ ]数组存储从1~n号city的第一条边的编号,first[i]存储i号city的第一条边的编号,初始时没有边加入,值都为 -1
用nest[ i]数组存储编号为i的边的下一条边。first[ ],next[ ]定义大小略大于roads 的最大值
存储代码:
for(i:1~roads)
{ cin>>u[i]>>v[i]>>w[i];
next[i]=first[u[i]];
first[u[i]]=i;
}
2.遍历邻接表
一号顶点的边的遍历
k=first[1];
while(k!=-1)
{cout<<u[k]<<v[k]<<w[k];
k=next[k];
}
遍历每个顶点的边
for(i:1~city)
k=first[i];
”””””””””””’
剩下同上
Bellman-Ford算法(解决:所有的点到某个定点的最短路径,与Dijkstra算法不同的是该算法能解决有负边存在的问题)
1.核心算法
对所有的边进行n-1次松弛操作
for(i:1~city-1) //n-1次松弛
for(j:1~roads) //每次松弛的具体操作
if(dis[v[i]]>dis[u[i]+w[i])
dis[v[i]]=dis[u[i]]+w[i];
其中dis[ i]数组表示编号为i的点到源点(0)的最短距离
对dis[]数组的初始化
for(i:1~n)
dis[i]=无穷大;
2.利用该算法解决是否存在负权边:
在进行完n-1次边松弛后,再进行松弛,若还能松弛,表示存在负权边
n-1次松弛后
check=0;
for(j:1~roads)
if(dis[v[i]]>dis[u[i]]+w[i])
{ check=1;
break;
}
check=1表示存在负权边
3.对算法复杂度的优化
增加一个bek[ ]数组,用来拷贝dis[ ]数组
每开始进行一次松弛操作前,将dis数组拷贝至bek数组中
在松弛操作结束后,新的dis数组与bek数组比较,相同,则表示已经更新完毕,break掉松弛操作;若不相同,则继续循环松弛