USACO 4.1.3 Fence Loops解题报告

 

USACO 4.1.3

Fence Loops解题报告

题意:

题目的意思就是,给很多边,边的信息包括,ID编号,长度,两端分别与哪些边相邻。

然后求一个最小的回路。

 

思路:

1.      求最小回路,只需枚举每条边。对于一条边,去掉这条边后,求出这条边两个端点间的最短路径,就可以算出关于这条边的最小回路。最后比较得到最小的回路就是所求的。

2.      求最短路径可以用dijkstra,但是这道题的存储方式是边,而且不是给的边的端点来表示边,而是直接给的边的ID。这样给题目带来不少麻烦。首先能想到的是,转换成用点表示的图。感觉可能很麻烦于是,我采用了直接用边做 dijkstra的方法

 

用边存储的dijkstra算法细节:

 

我的边的类:

class fence

{

public:

       intid;                    //ID

       intlength;              //长度

       intnl,nr;                //左、右边集数

       intSL[8],SR[8];     //边集具体内容

       intdis;                   //距离起始端点距离

};

       当然思想是一样的,都是用dijkstra的贪心思想。

       用一个优先队列priority_queue 存储可以走的边,,排序方法是,当前边距离起始端点的距离。

和传统的dijkstra不一样的就是,直接存储的可走的边,而不是可达的点,而且此边的dis一定是正确的。为什么?两条边进入同一点,但由于路径不同,两条边的dis可能不一样,但是由于采用的是优先队列,较远的到达这点的边永远是在后面的,所以不影响正确结果。可以这样想,每次更新队列,可达的下一个最近的点,是依托在一条边上的,而边在优先队列内的顺序是由距离dis决定的。所以可以保证队首的边,一定是到达下一个最近的点的边。

开始的时候,选择当前枚举的边的一端作为起始点(我是分为SL左边集,和SR右边集,我选的是SL左边集作为起始端),连着这一端的边集合,放到队列中,记录每条边到起始端的距离,当然第一批放进去的就是,边自身的长度了。然后就是不断从队列中取出首元素,计算他的另一端有哪些边,如果不在队列中,计算下这条边的dis,然后放进去。

找到路径的标志是,取出的队首元素,是当前所枚举的边的另一侧的边集合中的一个。在我的算法中,由于开始用从左边集SL中开始的,所以结束就是在SR中。

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值