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;}


0 0
原创粉丝点击