我是靠谱客的博主 谦让小刺猬,最近开发中收集的这篇文章主要介绍同余最短路概念:以简单的例题开始一道难一点的题再难一点的题目,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

概念:

属于最短路的拓展应用,常用于类似下面的模型:

已知一个带权图,现在需要求出从点 u u u 到点 v v v 是否存在一条路径,满足路径长度为 L L L,每条边可以重复经过。其中数据满足:
L ≤ 1 0 18     ∀ w ≤ 1 0 4 L leq 10^{18}~~~forall wleq 10^4 L1018   w104
当然,题目也可以换成求出一个区间 [ m i n L , m a x L ] [minL,maxL] [minL,maxL] 内的方案数,最小的合法长度,看题目的具体要求。

以简单的例题开始

题面[luogu P3403 跳楼机]

Srwudi的家是一幢 h h h层的摩天大楼。由于前来学习的蒟蒻越来越多,srwudi改造了一个跳楼机,使得访客可以更方便的上楼。

经过改造,srwudi的跳楼机可以采用以下四种方式移动:

  1. 向上移动 x x x层;
  2. 向上移动 y y y层;
  3. 向上移动 z z z层;
  4. 回到第一层。

一个月黑风高的大中午,DJL来到了srwudi的家,现在他在srwudi家的第一层,碰巧跳楼机也在第一层。DJL想知道,他可以乘坐跳楼机前往的楼层数。
h ≤ 2 63 − 1 , x , y , z ≤ 1 0 5 hleq 2^{63}-1,x,y,zleq 10^5 h2631,x,y,z105

题解(瞎吹)

如果不考虑 h h h的大小问题,那么我们可以得到一个简单的dp:
f ( i ) = f ( i − x )    V    f ( i − y )    V    f ( i − z ) f ( 1 ) = t r u e ( 或 运 算 符 用 V 表 示 ) f(i)=f(i-x)~~V~~ f(i-y)~~V~~ f(i-z)\ f(1)=true\ (或运算符用V表示) f(i)=f(ix)  V  f(iy)  V  f(iz)f(1)=trueV
因为 h h h过大,这个dp的时空复杂度过高,不能接受,因此需要进行优化。

最终上升到的楼层和操作的顺序没有关系,所以我们可以将一种操作堆积起来,将一个到达的楼层分解为:
h = a x + b y + c z h=ax+by+cz h=ax+by+cz
首先我们用最短路的方式求出数组 f ( ) f() f(),不知道怎么计算的到时候看代码
f ( i ) = min ⁡ h { h m o d    z = i } 其 中 h = a x + b y f(i)=minlimits_h{hmod z=i}\ 其中h=ax+by f(i)=hmin{hmodz=i}h=ax+by
翻译成人话就是用前两种操作到达一个高度h,这个高度和z取模的结果是i, f ( i ) f(i) f(i)表示的是最小的h。

求出这个 f ( ) f() f()之后,我们从楼层 f ( i ) f(i) f(i)出发,只用操作3能够到达的楼层有:
⌊ h − f ( i ) x ⌋ + 1         ( 1 ) lfloor{h-f(i)over x}rfloor + 1~~~~~~~(1) xhf(i)+1       (1)
那么这个答案是否有遗漏呢,假设我们从 f ( i ) f(i) f(i)出发,用操作1,2再走到了一个楼层 h ′ h' h,这个楼层依然满足 h ′ m o d    z = i h'mod z=i hmodz=i,那么可以得到:
h ′ = ⌊ h ′ z ⌋ z + i ∵ h = ⌊ h z ⌋ z + i ∴ h ′ − h = ( ⌊ h ′ z ⌋ − ⌊ h z ⌋ ) z h'=lfloor{h'over z}rfloor z+i\ because h=lfloor{hover z}rfloor z+i\ therefore h'-h=(lfloor{h'over z}rfloor-lfloor{hover z}rfloor)z h=zhz+ih=zhz+ihh=(zhzh)z
所以这个楼层 h ′ h' h其实也可以由 h h h使用几次操作3得到,也就说它会被计算到式子(1)中,不会被遗漏,那么我们最终的答案可以表示为:
a n s = ∑ i = 0 n ⌊ h − f ( i ) x ⌋ + 1 ans = sumlimits_{i=0}^n lfloor{h-f(i)over x}rfloor+1 ans=i=0nxhf(i)+1
这样的计算是不会用重复的。简单的证明(乱搞)如下:

使用反证法,如果同一个楼层能使用两种不同的方式得到,如果 x , y , z x,y,z x,y,z互不相等,那么:
a 1 x + b 1 y + c 1 z = a 2 x + b 2 y + c 2 z = h a_1x+b_1y+c_1z=a_2x+b_2y+c_2z=h a1x+b1y+c1z=a2x+b2y+c2z=h
两个多项式相等,则这两多项式最高次数相同,且对应次数项的系数相同.

那么得到
a 1 = a 2 , b 1 = b 2 , c 1 = c 2 a_1=a_2,b_1=b_2,c_1=c_2 a1=a2,b1=b2,c1=c2
显然两个方法其实是同一个。

如果 x , y , z x,y,z x,y,z有两个是相等的,那么就可以将这两个相等字母所在的单项式合并,依然是类似于上面的结果。

一道难一点的题

题面[luogu P2371 墨墨的等式]

墨墨突然对等式很感兴趣,他正在研究等式

a 1 x 1 + a 2 x 2 + … + a n x n = B a_1x_1+a_2x_2+…+a_nx_n=B a1x1+a2x2++anxn=B

存在非负整数解的条件,他要求你编写一个程序,给定 N N N { a n } {an} {an}、以及 B B B的取值范围,求出有多少B可以使等式存在非负整数解。

N ≤ 10 , ∀ a i ≤ 5 × 1 0 5 , 1 ≤ B m i n ≤ B m a x ≤ 1 0 12 Nleq 10,\forall a_ileq 5times 10^5,\1 leq B_{min}leq B_{max}leq 10^{12} N10,ai5×105,1BminBmax1012

题解(瞎吹)

显然用 [ 0 , B m a x ) [0,B_{max}) [0,Bmax)的方案数减去 [ 0 , B m i n − 1 ) [0,B_{min}-1) [0,Bmin1)的方案数就是题目要求的答案了。

找到序列 a a a中最小的元素 m m m,然后将序列中的每个元素分别对其取模,得到一个新的序列 t t t。这样的话,如果一个 B B B是合法的,那么 B + m x ( x ∈ N ) B+mx(xin N) B+mx(xN)也是合法的。而我们只需要知道一个对 m m m取模为 i i i的最小 B B B是多少,那么就知道在区间 [ 0 , B m a x ] [0,B_{max}] [0,Bmax]中有多少个数对 m m m取模为 i i i

首先我们做一个最短路,对于点 u ( u &lt; m ) u(u&lt;m) u(u<m)和点 ( u + a i ) m o d &ThinSpace;&ThinSpace; m (u+a_i)mod m (u+ai)modm建一条边权为 a i a_i ai的边,然后求出数组 f ( u ) f(u) f(u),其意义和上一道题目差不多。

而求出 [ 0 , B m a x ) [0,B_{max}) [0,Bmax)中的方案数可以使用这一条式子,而 [ 0 , B m i n − 1 ) [0,B_{min}-1) [0,Bmin1)的方案树也是类似的:

∑ i = 0 m − 1 ⌊ B m a x − f ( i ) m ⌋ + 1 sumlimits_{i=0}^{m-1} lfloor{B_{max}-f(i)over m}rfloor+1 i=0m1mBmaxf(i)+1

关于不重复和不遗漏的问题就交给正在看的各位dalao了。

再难一点的题目

题面

有一个有 n n n个点的无向图,共有 m m m条边,每一条边 e i e_i ei的边权为 w i w_i wi,现在要找到一条从点 1 1 1到点 n n n的路径,其长度恰好为 L L L。问是否存在这样的路径。
n ≤ 50 , w i ≤ 3 × 1 0 4 , l e n ≤ 1 0 18 nleq 50, w_ileq 3times 10^4, lenleq 10^{18} n50,wi3×104,len1018

题解(可能会TLE)

首先定义同余最短路的距离数组 d i s [ u ] [ m ] dis[u][m] dis[u][m]表示从开始到点 u u u,经过的路径长度 l l l是满足 l ≡ m      ( m o d    M ) lequiv m~~~~(mod~~M) lm    (mod  M)的最小 l l l,显然可以通过spfa求出。

对于与点 n n n直接相连的一个点 v v v,它们之间的边 e e e的长度为 w w w,显然到达该点之后在 e e e上来回走奇数数次后可以到达点 n n n,如果经过一条合法的路径(题目要求的路径)是经过这一条边的,那么 l l l可以分解为 l 1 + 2 a w l_1+2aw l1+2aw,而这个 l 1 l_1 l1要满足: l 1 ≡ l      ( m o d    2 w ) l_1equiv l~~~~(mod~~2w) l1l    (mod  2w),所以这个 l 1 l_1 l1可以被认为是 d i s [ v ] [ l m o d &ThinSpace;&ThinSpace; 2 w ] + 2 w dis[v][lmod 2w]+2w dis[v][lmod2w]+2w,那么如果式子可以表示 l l l那么就需要满足 d i s [ v ] [ l m o d &ThinSpace;&ThinSpace; 2 w ] ≤ l dis[v][lmod 2w]leq l dis[v][lmod2w]l,于是同余最短路中的 M = 2 w M=2w M=2w

那么最终的算法表示为:
枚举一个端点为 n n n的边,按照如上的方式计算出 d i s dis dis数组,接着判断。

最后

以上就是谦让小刺猬为你收集整理的同余最短路概念:以简单的例题开始一道难一点的题再难一点的题目的全部内容,希望文章能够帮你解决同余最短路概念:以简单的例题开始一道难一点的题再难一点的题目所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(48)

评论列表共有 0 条评论

立即
投稿
返回
顶部