专题四总结

来源:互联网 发布:客运站选址优化 编辑:程序博客网 时间:2024/05/29 18:05

这这个专题里面我们主要是跟图打交道。在整个大二,可以说一直都在和图打交道,离散数学离不开图,数据结构离不开图,acm当然也离不开图。图真的是非常重要啊,它深入到我们生活的各个方面,图在我们的生活中有着极大的用处,像一些网络线缆的铺设,还有修路的最短长度或是最少费用,这些问题在题目中都反映了出来。

在这个专题里面,树和图是这个专题的全部。对于树,我们的目的是给出一棵树,然后根据要求求出这棵数的最小生成树,这里面主要有prim算法和kruscal算法,我个人认为kruscalprim算法更加容易理解和掌握,kruscal用的是并查集进行点的合并,这个还是非常方便的,prim算法要用到队列,这无形之中就增加了算法的理解难度,在这里主要谈一下kruscal算法。这个算法的基本思想就是

1.对所有边从小到大排序;

2.依次试探将边和它的端点加入生成树,如果加入此边后不产生圈,则将边和它的端点加入生成树;否则,将它删去;

3.直到生成树中有了n-1条边,即告终止。

此算法的时间复杂度O(eloge),而prim的时间复杂度是O(n2),从这点来看,前者的效率更高的。

这这个专题里面,前几个题我都是用并查集+kruscal去解的,这类题目的一般解题步骤就是首先要建立数据模型,边如何存储,节点如何存储,像这其中有一道是关于二维平面图的连点最短距离的问题,这上面的点是采用二维坐标来表示的,跟之前的直接是一维整形数组去存储边就完全不一样了。建立数据模型之后,将边的权值按照规则去排序,一般都是从小到大排序,然后把每个节点都当作一棵独立的树,之后用并查集的方法,不在一棵树中的边合并,加上权值。这样直到所有的节点都在一棵树中。算法结束。

求最小生成树的问题相比单源点最短路径是这个专题里面比较简单的了,对于单源点最短路径问题,这个就牵扯到了图。求单源点最短路径的题我做的不多,这其中只用了spfa算法和dijkstra算法,我觉得后者的理解上虽然还算可以但是代码太复杂了,一不注意就晕了,并且这个算法对于权值为负数的时候是不适用的,局限性太大,因此布建议大家用这个算法。相比之下,spfa算法的性价比就很高了,用上个队列,建立起数据模型,一切就搞定了,容易理解,而且局限性小。

SPFA 其实就是Bellman-Ford的一种队列实现,减少了冗余,即松驰的边至少不会以一个d为∞的点为起点。

算法:

1.队列Q={s}

2.取出队头u,枚举所有的u的临边.d(v)>d(u)+w(u,v)则改进 ,pre(v)=u,由于d(v)减少了,v可能在以后改进其他的点,所以若v不在Q中,则将v入队。

3.一直迭代2,直到队列Q为空(正常结束),或有的点的入队次数>=n(含有负圈)。

一般用于找负圈(效率高于Bellman-Ford),稀疏图的最短路。

Spfa算法通俗点来说就是将起点入队,然后元素s出队,遍历所有的节点,之后找出和s有关联的节点,判断起点到这个节点的长度和起点到s的长度+s到这个节点的长度哪个小,若前者小,不做处理,后者小的话,修改距离,同时这个点入队,这样一直循环下去,知道队列元素为空。

就我个人而言,可能是因为之前就学过的原因,这个专题还是相对容易理解的。

0 0