继上次说的《清蒸火车》已经有一个多月了,我依然没有找到好的工作。除了RP的问题外,其实是自己没有对工作做好准备。不过在各种笔试和面试中,我发现了自己的知识的体系漏洞,现在补上去也还不晚。(*^__^*) 嘻嘻……
废话少说,进入主题。
题目要求.
输入最大中转点N(int) ,返回不大于N次中转点的所有乘车方案。
不难看出,这个问题近于穷举,类似于在集合{1,3,2,4,7,8,6,5,9}中找出不小于N的数字。
假如还不理解,那么可见下面连通图(圆表示城市,直线表示两点连通):
假定乘客需要从城市1到城市6,
那么乘车方案有:
A. {1,2,5,6}
B. {1,3,4,2,5,6}
C. {1,3,2,5,6}
……………等等
不就是最短路径嘛,一个解决。注意了,题目求的是所有解,而最短路径只是一个解。
有人会说,这个有什么意义么,请看情况:大连-南宁,最短路径:{ 大连,北京,南宁},但是当乘车时间在春节或者大学生寒暑假前后,那么这个路线肯定很拥挤,那么需要从大连到南宁的人会欢迎其它的中转方案。这时候最短的未必是最优的。
这里只考虑连通,不考虑额外的因素比如说两点连通距离。现在来分析一下应该如何下手,假定从城市1到城市6,已知信息集合为:
城市1:我和2,3,4连通
城市2:我和1,3,4,5连通
城市3:我和1,2,3连通
城市4:我和1,2,3连通
城市5:我和2,6,连通
解题步骤:
1. 城市1不能直接到6,于是委托和自己相连的2,3,4。哥们,你帮我看看谁能到6?
2. {2,3,4}发现自己不能直接到6,于是继续委托和自己相连的{ 城市}。哥们,帮我看看谁能到6?除非有城市能直接到六,否则重复2。
3. 城市5对委托人说,嗨,哥们,我能到城市6。城市2接到消息,说,嗨,城市5能到城市6。直到城市1接到信息。
这每个城市简直就是一个路由器嘛,能支持直接交付和间接交付。于是从路由表算法出发:
1.
2.
结合数据分析,中国通火车的城市约有3000个,很明显RIP不适用。那么OSPF是否可行?首先划分区域(AS)比较困难,因为单从火车车次数据中得不到划分区域的条件;其次,按区域划分得到34(确切说33个,因为大陆没有火车能到达台湾)个AS,构造各个AS里面的网络拓扑结构图会比较耗时。
那么有没有一种方法能在不知道网络拓扑结构的情况下得到连通图呢,在此暂不使用路由表算法,下一个版本将会考虑加入拓扑结构?
这时候从火车的数据结构分析,笔者采用(后来采用了字典)表示火车连通图,那么很容易想到 算法。不过这种情况没有启发条件。
假定还是从城市1到城市6,那么由城市1提供的信息得到候选解
{ 城市2,城市3,城市4},将城市1,城市2,城市3,城市4加入到已经遍历集合{K}
然后遍历{ 城市2,城市3,城市4}得到候选解
{
{ 城市1,城市3,城市4,城市5},
{ 城市1,城市2,城市4},
{ 城市1,城市2,城市3}
}
背景灰色的城市表示已经在已遍历表中出现的,未能连通道6的城市。
那么下一步剩下{ 城市5},得之其能连通城市6。
回溯得到,5->6,2->5-6,1->2->5->6。
运行示意图:trainAdvice.GetTransfer("金城江", "丹东",3);// 起始点 终点 最大中转数
在这里感谢:
建议的卢春成的文章
源代码和数据:
ps:暂不支持城市与城市车站不相符合的查询,比如武汉,将会在下一个版本更新。