图论-最短路

用点代表事物,用连接两点的线表示相应两个事物间具有这种关系。
图G=(V,E)V:点(事件),E:边(点与点之间的关系)

Floyd算法
O=V^3。
插点法, 从图的 带权邻接矩阵A=[a(i,j)] n×n 开始, 递归 地进行n次更新。
即由矩阵D(0)=A,按一个公式,构造出矩阵D(1);又用同样地公式由D(1)构造出D(2);……;最后又用同样的公式由D(n-1)构造出矩阵D(n)。
矩阵D(n)的i行j列元素便是i号顶点到j号顶点的最短路径长度,称D(n)为图的距离矩阵,同时还可引入一个后继节点矩阵path来记录两点间的最短路径。
map[i,j]:=min{map[i,k]+map[k,j],map[i,j]}; //map[i,j]表示i到j的最短距离,k是穷举i,j的断点。

Dijkstra算法
O=V^2。
基于 的迭代(每次找最短的那个 ),它只能求正权最短路。
负权回路:走一圈是负数(不存在最短路)
如果边有负,则该算法可能会有错误。

Bellman-ford算法
O=|V|*|E|。
基于 的迭代。
稳定、支持负权。
无回路:n个点,n-1条边
x能否对y松弛:
rel=false;
for每条边(x,y)
if ((dis[x]+len[x][y])
rel=true;
外圈循环n次:判断负权回路。
边表:struct里定义x(起点)、y(终点)、v(权值),然后e[i].x、e[i].y、e[i].v

例题:香甜的奶油(边)、虫洞(连通图、判断有没有负权回路)。

SPFA算法:
对迭代的改进:用队列存放刚被松弛过的点。(出队后标记为真再改成假)
for(int i=link[x];i;i=e[i].next)
if(vis[i]=false)vis[i]=true;
......
vis[i]=false;//出队列再标记为假
怎么判断图上的负环:某个点被更新n次(进队次数>=n)。


你可能感兴趣的:(c++,知识点)