去年联合训练的一道题,题意大致是:
最短路,求使卡车高度尽量高的情况下的最短路径。
即求st->ed可通的情况下卡车高度的最大值,并求在该最大高度下的最短路径。
(实际上就是路径上最小高度的最大值)
比较传统的算法是二分高度+最短路。
00445323 | 2010-07-02 15:31:47 | Accepted | 1011 | 640 MS | 8280 KB | Visual C++ | Slave_wc |
采用的第二种算法是,两次最短路,去年比赛的时候还不会二分,就在那里想改Dijkstra来求最小高度的最大值。
比赛时高度和距离放一个Dijkstra里更新,错的,呵呵,赛后改用两次最短路最朴素的Dijkstra跑了500ms。
Dijkstra是贪心的策略,稍微想一下,就可以发现采用贪心同样可以求得路径上最小高度的最大值。
像一般的Dijkstra一样更新,只是更新的dis保存最小高度的当前最大值。每次找的是更新得到的最小高度里的最大值(确定其为最大)...
pass:
因为一条路径st->v0->v1->...->vn。
从st 到当前点 vi 的最小高度的值总是越往后越小的。
所以每次从更新的点里找一个最小高度里最大的点, 因为 current(最大) >= else >= 所有的从(else->j)else出发更新的值。
所以就可以确定当前取得的就是最大的。
其实Dijkstra本质上就是广搜。现在习惯了用priority_queue来写。
下面是邻接阵的。
00445409 | 2010-07-02 20:29:30 | Accepted | 1011 | 359 MS | 8248 KB | Visual C++ | Slave_wc |
又用邻接表写了下,快了200多ms。
0445514 | 2010-07-03 10:11:39 | Accepted | 1011 | 140 MS | 7956 KB | Visual C++ |
算法三:并查+最短路
昨天写了1598 / find the most comfortable road
总算过了,不过算法是从网上看的,在最短路的专题里,一直考虑用最短路,思维定势了,wa无数次,
根本想不到去用并查。
后来继续尝试用最短路--超时了,应该能用最短路做,暂时只会并查的做法,比较直白也相对简单。
早上起来想到Trucking这题也可以用并查的,用并查可以很容易求得最小高度的最大值。
于是又重写了下,跑了203ms, 比两次最短路稍微还慢一点,可能是因为边数比较多把。
一条路径上的最小高度,可想而知是使这条路径 (st->ed) 连通的权值里最小的。
所以我们可以先对边sort(大->小), 那么最小高度的最大值即是, 在不断加边的过程中第一个使st->ed 连通的高度值。
下面是这题 并查+最短路的邻接表实现
00448133 | 2010-07-06 08:00:32 | Accepted | 1011 | 203 MS | 7980 KB | Visual C++ | Slave_wc |