这是本蒟蒻博客的第一篇文章,不规范之处敬请各位大佬指正和谅解orz
前言
本蒟蒻写博客发题解主要是为了加深对题目的理解,并且在枯燥的刷题过程中换换脑子理清思路,毕竟该蒟蒻博客很可能只有我一个人看(或者两个?),不管怎么说,一定会认真对待的。
Pass:声明:本博客参考:
P4009 汽车加油行驶问题(分层图最短路)_Mr.Gzj的博客-优快云博客
一、建模
这道题其实代码和实现难度都很低,关键在于如何建模。
显然看到网络流24题基本上各方神犇都去跑最小费用最大流了,但蒟蒻这里提供另外一个方法——
分层图最短路
既然是求最小边权,我们容易想到是以费用为边权建图。
那么问题来了,如何建图呢?
网格图,那么最基本的就是根据题意描述,向四个放向连边。
但这道题真正难在对汽油的处理。
我们发现,汽油这一状态较为复杂.。
这里就需要引入分层图了。
把图复制若干张,对于每张图表示不同的状态,根据题意对不同的图层进行连边,这就是分层图。
题目中油箱容量为K
——实际上根据题目描述是满油可以走K条网格边,
这里曲解为油箱容量为K,每走一条边消耗一单位的油,方便理解——
所以我们需要建K+1张图,表示油箱含有0-K个单位的油
(也可以表示用了0-K单位的油,实现时微调即可)
如果要加满油,就向第K层(即油量为K的层)连边,
对于每一步,向下一层(假设是当前第Lay层,则下一层为Lay-1层(下同))连边
二、代码实现
1.节点在图中的编号(分层图的存储)
我们不妨把编号理解为一个点在图中的次序。
对于每一张网格图,行编号小的次序靠前,在同一行,列编号小的次序靠前。
那么对于K+1张图,依次排列即可。
节点的编号边是在它前面(次序比它小的)的节点的个数+1。
假设点p在第k张图的(i,j),那么它前面的节点数有:
前面图层的节点数n*n*k(存在第0层所以k不用减一)
前面行的节点数n*(i-1)
所在行前面的节点数(j-1)
加起来再加一即可
求编号代码如下:
int Get_Node(int x,int y,int z)//第z层的(x,y)的编号
{
return (n*n*z)+(n*(x-1))+y; //下层节点数+该行前节点数+列编号
}

最低0.47元/天 解锁文章
562





