POJ3255Roadblocks
来源:互联网 发布:剑三毒姐妖娆捏脸数据 编辑:程序博客网 时间:2024/06/06 05:12
1. POJ3255Roadblocks
这道题求次短路径。我是按照《挑战程序设计竞赛》这本书的代码来写的,我就来解释一下这本书关于这道题的写法。
首先,这本书提到“到某个顶点v的次短路要么是到其他某个顶点u的最短路再加上u->v的边(显然u->v并不形成源点到v的最短路),要么是到u的次短路再加上u->v的边(显然这里u->v的边就是源点到v的最短路了)。”而另外一些博文提到先求出源点到v的最短路,然后逐次替换每一条路径换上另外一条,判断新生成的路径中的最小值,这也是一种思路。
从代码来分析这本书的思想,作者用了下述的方法进行Dijkstra寻最短路。其实中心思想就是:先找出最短路,然后找出长于最短路的最短路(即次短路)。方法是找到比当前某点的最短距离dist[e.to]要短时的最短路方法,然后就按Dijkstra的方法更换,并且判断如果老的(被更换的)那条比次短距离dist2[e.to]要短时,那就也替换,相当于进行两次Dijkstra,根据不同的判断依据找出两条路。
while(!que.empty()){ P p = que.top();que.pop(); int v = p.second,d = p.first; if(dist2[v] < d ) continue; for(int i = 0;i <(int) G[v].size();i++){ edge &e = G[v][i]; int d2 = d + e.cost; if(dist[e.to] > d2){ swap(dist[e.to],d2); que.push(P(dist[e.to],e.to)); } if(dist2[e.to] > d2 && dist[e.to] < d2){ dist2[e.to] = d2; que.push(P(dist2[e.to],e.to)); } } }
直到第11行都是Dijkstra的普通方法,用于找到最短路。只是要注意这里用了swap函数,为什么要用这个函数呢,就是为了下面对次短路径进行判断时,要看这条被替换的旧的最短路径是不是比原有的次短路径要短;同时注意swap之后,假如第一个if经过的话第二个if的第二个判断条件肯定是对的,那就用第一个判断条件来找出最短的次短路径。如果没经过第一个if,那第二个if的第二个判断条件也肯定是对的,因此还是通过第一个判断条件来找最短的次短路径。意思就是,找到一条即比最短路dist[e.to]要长,又在对每个子路径的遍历中找到最短的一条,从而找到次短路径。
还要注意的是因为采用了优先队列,所以相当于广搜,所以正确性得到了保证。
但是这道题我用这个代码提交POJ,那里老是说我CE,我也不知道问题在哪,先把自己的想法写上去吧。
/* * POJ3255Roadblocks.cpp * * Created on: 2014年7月16日 * Author: Prophet */#include<stdio.h>#include<algorithm>#include<vector>#include<queue>using namespace std;struct edge{int to,cost;//to:到达的点;cost:边的权值};const int MAX_N = 100010;#define INF 1000000typedef pair<int,int> P;//first是最短距离,second是顶点的编号vector<edge> G[MAX_N];int dist[MAX_N];//记录最短路int dist2[MAX_N];//记录次短路int x,y,z;int n,r;int main(){while(scanf("%d%d",&n,&r)!=EOF){for(int i=0;i<n;i++)G[i].clear();for(int i=0;i<r;i++){scanf("%d%d%d",&x,&y,&z);x--;y--;G[x].push_back(edge{y,z});G[y].push_back(edge{x,z});//双向}//**********解题部分**********std::priority_queue<P,std::vector<P>,std::greater<P> > que;std::fill(dist,dist+n,INF);std::fill(dist2,dist2+n,INF);dist[0]=0;que.push(P(0,0));//距离原点(编号为0)的最短距离为0while(!que.empty()){ P p = que.top();que.pop(); int v = p.second,d = p.first; if(dist2[v] < d ) continue; for(int i = 0;i <(int) G[v].size();i++){ edge &e = G[v][i]; int d2 = d + e.cost; if(dist[e.to] > d2){ swap(dist[e.to],d2); que.push(P(dist[e.to],e.to)); } if(dist2[e.to] > d2 && dist[e.to] < d2){ dist2[e.to] = d2; que.push(P(dist2[e.to],e.to)); } } }printf("%d\n",dist2[3]);}return 0;}
- POJ3255Roadblocks
- poj3255Roadblocks之dijkstra解法
- 分类算法-----KNN
- iOS:UITableViewCell 方法 属性 详解
- unity3D游戏开发九之雾效、水效和音效
- C语言中volatile关键字的作用
- jsp+servlet+mysql+javabean写的登陆注册页面
- POJ3255Roadblocks
- 关于S3C2440的LCD只能显示2张图片,不能显示多张图片的问题
- unity3D游戏开发十之粒子系统
- httplib2 post 问题
- H264 编解码知识
- unity3D游戏开发十一之物理引擎
- STM32 触摸屏触摸功能学习总结
- 顺序容器的5种初始化方法
- c++builder XE6 添加属性 方法