-1.前置知识
最短路,图论
0.大体思路
对每条航线进行建边处理,同时记录两个城市之间的城市数(这里题目中的经过多少城市指从$u$到$v$不包括首/尾的城市数),然后跑$Dijkstra$即可
1.建边
本题由于边数较多,采用邻接矩阵存图较为合适。
定义$cost[i][j]$表示从$i$到$j$的最少费用,$to[i][j]$表示在费用最少的情况下从$i$到$j$所经过的最少城市数
假设一条航线的费用是$money$,有$len$个城市,对应的编号分别为$x_{1},x_{2},···,x_{len}$
首先要明确一个常识性问题:在一条航线上,一个城市不能飞到它之前的城市
所以我们可以得到一个显然的建边方法,对于一条航线的$x_{i}$,向$x_{j}(i<j<=len)$建一条长度为$money$的边。需要注意的是,如果之前$cost[i][j]$已赋值,则
如果$money<cost[i][j]$,需要更新$cost[i][j],to[i][j]$
如果$money=cost[i][j]$,则如果$i$到$j$之间的城市数$<to[i][j]$,更新$to[i][j]$
这样就可以满足在花费最少的情况下经过的城市数最少
2.Dijkstra
定义$c[i]$为起点到$i$的最少花费,$ans[i]$为起点到$i$之间经过的城市数
假设当前从城市$k$开始拓展。
如果$k$与某个城市$i$有连边$cost[k][i]$,我们可以类比之前建边的方法进行更新。
如果$c[k]+cost[k][i]<c[i]$,更新$c[i],ans[i]$
如果$c[k]+cost[k][i]=c[i]$,如果$ans[k]+to[k][i]<ans[i]$,更新$ans[i]$
其中$ans[i]$的更新是指$ans[i]=ans[k]+to[k][i]$
根据定义,$ans[i]$表示起点到$i$的城市数,$ans[k]$表示起点到$k$的城市数,$to[k][i]$表示$k$到$i$之间的城市数,所以很明显有$ans[i]=ans[k]+to[k][i]$
3.Code
1 |
|