hdu 2962 Trucking(二分+最短路)
来源:互联网 发布:动态图修改软件 编辑:程序博客网 时间:2024/05/22 03:13
题目
http://acm.hdu.edu.cn/showproblem.php?pid=2962
题意:卡车要运输尽可能高的货物(但不高于一个安全值),城市间每一条路是双向的但是都有高度限制。求解运输尽可能高的货物时,卡车到达目的地的最短路径。
解题思路
单源最短路径的变形,在最短路径基础上加了高度限制。
思路:采用二分搜索法+修改的Dijkstra,取高度最大的最短路径就是答案。(当枚举太慢,且每次判断都只有两种可能时,优先考虑二分)
先求高度mid=(l+r)/2,若在mid的高度限制下,Dijkstra函数能到达终点(判断dist[dest]的值是否有效),则继续试探[mid+1, r]这一段,否则试探[l, mid-1]这一段。用maxH记录每一次能通行的高度mid并更新,shorteset记录mid高度下通行的最短路径长度。
在Dijkstra函数的实现可以是朴素的,也可以是最小优先队列优化的,两者实现上分别要注意:
- 由于涉及多次调用,因此都要把visited数组初始化为false。
松弛时都要保证height[pos][k]大于限制高度。
朴素Dijkstra:原本dist数组是初始化为cost[s][i]的,但如果height[s][i]小于了限制高度,则要初始化为INF,这一点需要注意!
- 最小队列优化Dijkstra:dist数组要初始化为INF,因为松弛是从源点开始的,只有源点的dist要先赋值为0。
AC代码
#include <iostream>#include <algorithm>#include <queue>#include <vector>using namespace std;const int maxn = 1005, INF = 1 << 27;typedef pair<int, int> P; //first代表距离,second代表顶点编号int n, road;int cost[maxn][maxn], height[maxn][maxn]; //记录两点间代价和高度int dist[maxn];bool visited[maxn];void init(){ fill(height[0], height[0]+maxn, INF); for (int i = 0; i <= n; ++i) for (int j = 0; j <= n; ++j) cost[i][j] = (i==j) ? 0 : INF;}void dijkstra(int s, int h) //朴素dijkstra{ fill(visited, visited+maxn, false); //由于多次调用,visited每次要在函数里初始化 for (int i = 1; i <= n; ++i) dist[i] = (height[s][i] < h) ? INF : cost[s][i]; //如果高度不够则标记无法通过 visited[s] = true; while(1) { int pos = -1, mindist = INF; for (int i = 1; i <= n; ++i) //选出当前离源点最近的点 { if (!visited[i] && dist[i] < mindist) { mindist = dist[i]; pos = i; } } if (pos == -1) break; //结束 visited[pos] = true; //标记pos访问过 for (int k = 1; k <= n; ++k) { if (!visited[k] && dist[pos] + cost[pos][k] < dist[k] && height[pos][k] >= h) //松弛要保证高度能通过!! dist[k] = dist[pos] + cost[pos][k]; } }}void dijkstra_optimized(int s, int h) //最小优先队列优化的dijkstra{ priority_queue<P, vector<P>, greater<P> > q; //初始化visited和dist! fill(visited, visited+maxn, false); fill(dist, dist+maxn, INF); q.push(P(0, s)); dist[s] = 0; visited[s] = true; while(!q.empty()) { P out = q.top(); q.pop(); int pos = out.second, d = out.first; if (d < dist[pos]) continue; //取出的不是最短距离 visited[pos] = true; //标记取出的pos被访问过 for (int k = 1; k <= n; ++k) { if (!visited[k] && d + cost[pos][k] < dist[k] && height[pos][k] >= h) //松弛要保证高度能通过!! { dist[k] = d + cost[pos][k]; q.push(P(dist[k], k)); } } }}int main(){ ios::sync_with_stdio(false); int kase = 0; int a, b, h, c, src, dest, limit; while (cin >> n >> road && n && road) { if(kase) cout << endl; kase++; init(); for (int i = 0; i < road; ++i) { cin >> a >> b >> h >> c; cost[a][b] = cost[b][a] = c; h = (h == -1) ? INF : h; //-1表示高度无穷大 height[a][b] = height[b][a] = h; //记录两点间高度 } cin >> src >> dest >> limit; int l = 0, r = limit; int shortest = INF, maxH = INF; //对限制的高度二分, 使其能通过且最大 while(l <= r) { int mid = (l+r)>>1; dijkstra_optimized(src, mid); if (dist[dest] != INF) { l = mid+1; //左界扩大 shortest = dist[dest]; maxH = mid; } else r = mid-1; //右界缩小 } cout << "Case " << kase << ":" << endl; if (shortest == INF || maxH == INF) //无法通过 cout << "cannot reach destination" << endl; else { cout << "maximum height = " << maxH << endl; cout << "length of shortest route = " << shortest << endl; } } return 0;}
阅读全文
0 0
- hdu 2962 Trucking(二分+最短路)
- HDU 2962 Trucking 最短路+二分
- 【HDU】2962 Trucking 二分+最短路
- hdu 2962 Trucking (二分+最短路Spfa)
- HDU 2962 Trucking 二分+最短路
- hdu 2962 Trucking (最短路之SPFA算法 + 二分)
- HDU 2962 Trucking 最短路
- HDU-2962-Trucking(最短路)
- HDU 2962 Trucking 最短路。。
- HDU 2962 Trucking 最短路
- HDU 2962 Trucking(二分+带限制最短路)
- hdu 2962 Trucking 最短路+二分。。Dijkstra+SPFA两种算法实现。
- hdu 2962 Trucking(二分最大可行的高度+最短路dijkstra)
- HDU 2962 Trucking 二分+最短路(带限制最短路)\\不满足递推关系,不能直接是spfa
- 【最短路+dijkstra+spfa】杭电 hdu 2962 Trucking
- hdu 2962 Trucking 二分 + Dijsktra
- HDU 2962 Trucking(Dijkstra+二分)
- hdu 2962 Trucking【二分+SPFA】
- JNI开发流程
- Spring 源码之 BeanDefinition阅读
- SpringMvc的DispatcherServlet和Control的线程安全问题
- DFS、栈、双向队列:CF264A- Escape from Stones
- NGUI 类皇室战争(CR)的滚动列表效果完整实现(四)
- hdu 2962 Trucking(二分+最短路)
- POJ 1020 Anniversary Cake(dfs+分割思想)【转】
- 有意思的程序员
- hdu 1254 推箱子 (bfs+dfs+预处理)
- java计算器,可以运算括号
- 【机器学习】支持向量机
- iOS mac终端下的SQL语句
- 狐狸找兔子—php实现
- C++ Primer Plus p-189-6.14-cingolf.cpp