问题来源:
前两天做了一道图论的ACM题目,其中包含搜索两点之间是否连通
这样一个子问题,当初做的时候用的是STACK实现的深度优先搜索,
然后拿给朋友看时,她竟然来了句太神奇了,你竟然用深搜,怎么不用
广搜呢?
也许效率更高呢!
好吧,当时对深搜和广搜的效率没有探究过,然后听从朋友的意见改成
了广搜一试,结果竟然TLE了...好吧,我承认自己在做那一题时用的算
法相当差劲,即使通过了也花费了860MS的时间,可是同样的搜索,换
成广搜就超时了,当时觉得不可思议,因为从理论上说,两种搜索算法在
时间上的效率是一样的.
然后忽然就回忆起那么一小段话:"在判断是否存在路径问题上,深度优
先搜索速度是高于广度优先搜索的",然后去网上查了查,找不到关于这
个问题的详细解答...在告诉另一个同学LC这个思想的时候,他竟然上来
就说了句"Mao~",呃~
好吧,争吵是不对的,但对问题的探求精神还是值得继续的,趁此机会验
证一下,上面这个想法是否在实践上值得考虑.
问题模型:
给出一无向无权图,判断要求的两点之间是否连通.
输入:
n,m分别代表顶点数和边数
接下来有m行,每行一对整数u,v,表示
点u,v之间有一条边;
接下来一个整数q,表示有q组查询;
每组查询两个整数,f,t表示从f到t的搜索;
输入样例:
5 5
1 3
1 5
2 5
2 4
3 2
3
1 2
3 4
1 4
这个简单的问题模型可以用来简单验证DFS和BFS的效率问题,简单,
所以实效、清晰,嘿嘿~
实践思路:
写出该问题模型的主框架,用于接受输入,及时间统计,其中,图的存储用到邻
接表.有一个AddEdge()函数增加边,然后分别写出几个实现搜索算法的函
数,其中Dfs()为递归实现的深搜,Dfsstk()为栈实现的深搜,Bfs()为广搜.
好吧,写好算法的实现,数据的生成就需要另外写程序解决了,最简单的就是
用随机函数了,这个就不多说啦~待会儿看程序.
实现过程:
未使用STL 提供的queue和stack
偿试递归深搜和栈深搜
用队列实现广搜
用邻接表存储图
好吧,程序写好了,下面就要写另外的程序来生成这些数据了
生成数据之后测试时发现,同样的数据,分别多次进行运算之后,
进行的运算时间消耗竟然相差很多,可能由于进程交替、运行环
境不稳定等原因造成的,所以,对于每组样例,都进行了20次执行,
来得到其总运行时间,这样可以消去一些偶然原因造成的不均衡
结果.
好吧,至此,终于差不多完成了~
首先看一下运行的统计结果:
(每类数据100组,
n个顶点,
n*log(n)*0.5条边,
n*log(n)*0.5次查询
(20次执行总耗时))
WinXP CPU:AMD Athlon(tm)II X2 215 Processor
关于深搜和广搜在图两点间是否连通的判断问题中的统计对比(单位:ms)
n 10 50 100 200 500 1000
DFS 0 77 992 3470 32529 150396
BFS 15 200 2061 7606 90476 385236
DFSSTK 15 61 1078 051 57552 250355
代码如下:
算法代码
数据生成代码
总结:就好像快排的一般效率是高于堆排一样,此处给我们以关于深搜和广搜更深层次
上的认知,嗯,在以后用到相关算法时,这些数据也能给我们以启示吧.
另:感谢LC同学帮助记录统计的数据~