基本算法dijkstra的POJ水题推荐

首先转载一个别人归纳的题目集合:

1.poj1062 昂贵的聘礼(中等)
    此题是个经典题目;用Dijkstra即可;但是其中的等级处理需要一定的技巧;
   要理解好那个等级制度;这个处理好,基本就是裸体Dijkstra;
2 poj1125 Stockbroker Grapevine(基本)
   这个是简单Floyd,需要求出的是每对顶点之间的最短路径;
   然后找到那个所需时间最小的那个人中的所需时间;
3,poj 1502 MPI Maelstrom(基本)【已经解决之,Dijkstra直接水之】
    这题是邻接矩阵的Dijkstra就可以解决的;
    直接水之;
4,poj 1511 Invitation Cards(中等)
    这个时间上有点卡了。Dijkstra,bellman可能会TLE;用SPFA+邻接表可以过的;
    有个地方注意一下就好了,每个志愿者回来的时候的最短路径;将原图的每条边反向一下,对端点1再来
    SPFA就可以来;
    正向图的结果+逆向图的结果就是所求;
5,poj 1724 ROADS(中等偏上)
    题意是在一定的coins的限制下的最短路径;可以用Dijkstra的变形;
    用邻接边来存储边;
    松弛过程中用优先队列(边的长度短的优先)来存储边,将符合条件(coins限制)的边都加入优先队列;
    直到找到延伸到最后一个顶点即可终止循环; 因为最先到达的一定是最短路径,在coins的限制条件下;
6,poj1797 Heavy Transportation(中等)
    从端点1到端点n的能够通过的最大载重;
    可以用Dijkstra变形一下,在松弛时要改变一下松弛的条件;
    另外results数组中存储的不是每个点到1的最短距离,而是能够通过的最大载重;
    这题的输出让我灰常无语,以后输出要看清啦。。
7,poj 1860   currency exchange(基本)
    这个是bellman_ford的经典应用;
    一个套汇问题,就是通过一系列的货币交换能够到达价值增加的目的;
    就是类似判断有没有负权回路;
    类似与poj2240,poj3259;
8,poj2240 Arbitrage(基本)http://hi.baidu.com/lewutian
    这个是poj1860的简化版本;就不多说了。。
    直接bellman水之;
9,poj 2253 Frogger(中等)
    和poj1797类似,所求的正好相反,也是Dijkstra的变形经典应用;
    改变一下松弛时的条件;
10,poj 2387   Till the Cows come home(基本)
     注意其中可能有重边;然后就是赤裸的Dijkstra;
11,poj 2502    Subway(基本)
    可以用Floyd来搞定,关键是哪个边的存储,存储后就是灰常简单的Floyd了;
12,poj 3013 Big Christmas Tree(中等)
    这个要有个重要的转化;首先price of an edge will be (sum of weights of all descendant nodes) × (unit price of the edge).
    这句指出每条边的代价为该边所有子孙节点权值之和乘以该边的权值。
    换个角度就是每个节点的代价为该节点到根节点的所有边的权值乘以该节点的权值。
   其实就是求从端点1到每个点的最短路径*改点的权值,,然后之和;
    貌似,数据有点大,用SPFA吧。。
13,poj 3037 Skiing(中等)
    这个题有点意思;刚开始想用bfs;
    后来发现对于每个点从该点出发的速度是恒定的,例如从a->b->c;则c出发的速度就是V*2^(A-B)*2^(B-C)=V*2^(A-C);
    所以直接求最短路径就可以了,边也知道了。用spfa。。
14,poj 3159 Candies(中等)
    我靠,这个题时间卡的好紧啊!我的spfa是1400ms,时限是1500ms,汗一下;
    题意有点难理解,想明白了,其实就是求一个从1->n的最短路径;
15,poj 3259 Wormholes(简单)
    这个题和poj1860,poj3259基本一样;
    求负权回路是否存在;用bellman直接水之;
16,poj 3268 Silver Cow Party(基本)
    Dijkstra可以直接过的。。只不过求的有变化;
17,poj 3377Ferry Lanes(中等)
    这题可以用最短路做的;但是我看和导论那个流水线那个dp例子灰常像;
    于是就dp过了,其中有个地方需要注意,dp的话,就是可以需要检查两端的情况;
    有兴趣的可以两种都试试;
18,poj 3615 Cow Hurdles(中等)
    Floyd求出每个端点之间的路径中最大高度是最小的那个最大高度;
    要改变一下松弛的条件;  
19,poj 3660 Cow Contest(中等)
    这个题有点topsort的意思,其实可以用Floyd来做,而且用的很巧妙;
    邻接矩阵中用0,1,2来分别存储关系不能确定,在之前,在之后;
    然后判断每个点哪行,如果除了对角线处,没有0出现的话,那么它的位置就可以确定了。。


dijkstra所需的数据结构:

dist[]数组,用于存储每个点的前缀点,可以从终点回溯整个最短路径;

shortest[]数组,用于存储目前该点的最短距离;

ifVisited[]数组,用于将已经找到最短路径的点筛选出去。

回顾一下dijkstra的几个基本步骤:

1.初始化起点,初始化所有数组,起点的shortet设置为0;

2.开始遍历所有点V次,V为顶点数目-1;

3.每次遍历的开始,选出shortest的顶点,将ifVisited置为true;

4.遍历过程中,如果当前筛选出的点的dist+两点间距离<某个点的shorest,则更新该点的shortest;


最终,shortest记录的是原点到每个点的最短距离。


局限性:dijkstra不能求出任意两个点之间的最短路径,只能求出某一点到其他任一点的最短路径,并且不支持负权边;

如果要支持负权边,则使用bellman-ford,如果要支持任意两点最短路径,需要使用flyod。

你可能感兴趣的:(各类ACM题目)