学习总结2019/5/29

今天晚上做了一份题。三个小时的时间,A掉了三道题,虽然中间有过一定的干扰,但这效率实在是有些低了。大部分题目的难度不算大,是比较常见的题型,效率低我觉得一个很重要的原因是不熟练——对知识掌握的不熟练,对掌握的知识运用的不熟练。特别是学的比较早的,很多都忘记了,以后要注意加强复习和练习。

Dijkstra算法:用来计算从一个点到其他所有点的最短路径的算法,不能处理存在负边权的情况。
算法描述:
设起点为s,dis[v]表示从s到v的最短路径,pre[v]为v的前驱节点,用来输出路径。
dis[v]=∞(v≠s); dis[s]=0; pre[s]=0; //初始化
For (i = 1; i <= n ; i++)
1.在没有被访问过的点中找一个顶点u使得dis[u]是最小的。
2.u标记为已确定最短路径
3.For 与u相连的每个未确定最短路径的顶点v
if (dis[u]+w[u][v] < dis[v])
{
dis[v] = dis[u] + w[u][v];
pre[v] = u;
}
算法结束:dis[v]为s到v的最短距离;pre[v]为v的前驱节点,用来输出路径。

Bellman-Ford算法:计算从一个点到其他所有点的最短路径的算法,能够处理存在负边权的情况,但无法处理存在负权回路(边权之和为负数的一条回路)的情况
算法实现:
设s为起点,dis[v]即为s到v的最短距离,pre[v]为v前驱。w[j]是边j的长度,且j连接u、v。

dis[s]=0,dis[v]=∞(v≠s),pre[s]=0//初始化
For (i = 1; i <= n-1; i++)
For (j = 1; j <= E; j++)         //注意要枚举所有边,不能枚举点。
   if (dis[u]+w[j]<dis[v])          //u、v分别是这条边连接的两个点。
    {
       dis[v] =dis[u] + w[j];
       pre[v] = u;
  }

SPFA算法:Bellman-Ford算法的一种队列实现
算法实现:
dis[i]记录从起点s到i的最短路径,w[i][j]记录连接i,j的边的长度。pre[v]记录前趋。
team[1…n]为队列,头指针head,尾指针tail。
布尔数组exist[1…n]记录一个点是否现在存在在队列中。
dis[s]=0,dis[v]=∞(v≠s),memset(exist,false,sizeof(exist));//初始化
起点入队team[1]=s; head=0; tail=1;exist[s]=true;
do
{
1、头指针向下移一位,取出指向的点u。
2、exist[u]=false;已被取出了队列
3、for与u相连的所有点v //注意不要去枚举所有点,用数组模拟邻接表存储
if (dis[v]>dis[u]+w[u][v])
{
dis[v]=dis[u]+w[u][v];
pre[v]=u;
if (!exist[v]) //队列中不存在v点,v入队。
{//尾指针下移一位,v入队;
exist[v]=true;
}

}
while (head < tail);

循环队列:
  采用循环队列能够降低队列大小,队列长度只需开到2*n+5即可。例题中的参考程序使用了循环队列。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值