POJ 3255 次短路问题+Dijkstra最短路优化问题

来源:互联网 发布:机箱设计软件 编辑:程序博客网 时间:2024/04/28 21:41

这个题真的是卡了我一天之久。。。倒并不是说它难。有一个地方一直没注意到结果一直wa。。。恶心的我都差点放弃了。。。好在最后改出来。。。这题懂得方法之后并不难。。就只是一个简单地Dijkstra求最短路问题。

题意:给出一些点和一些路径,让你找到倒数第二条最短路径。

分析:要是找到最短路径就好办了,直接无脑套用bellman-Ford或者Dijkstra就可以了,但题目让求次最短路径。想一想。次最短路径不就和最短路径一样么。无非就是再加一个数组,然后求最短路径的过程中顺便维护一个次短路径不就好了。好了,那就直接写呗。

唉,这一点就比较坑了。。。因为输入的路径没有负数,所以我一上来想到的是spfa算法。。。结果TL了。。。。。然后又换的Dijkstra,但是大佬们都说spfa可以过。。。反正用Dijstra过了。。而且这个算法还比spfa稳定。所以就不管了吧。直接上代码:

#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<queue>#include<vector>using namespace std;const int maxed=5000+10;#define INF 0x3f3f3f3ftypedef pair<int,int> P;//这个地方我采用的是邻接表法来储存的这些点和权值struct Node{    int en,val;};int n,r,d[maxed],d2[maxed];//d数组表示最短路径数组,d2数组表示次最短路径数组vector<Node> ve[maxed];int main(){    void slove(int);    scanf("%d%d",&n,&r);    int a,b,c;    for(int i=0;i<r;i++){        scanf("%d%d%d",&a,&b,&c);        Node n;        n.en=b;        n.val=c;        ve[a].push_back(n);        n.en=a;        ve[b].push_back(n);    }    slove(1);    printf("%d",d2[n]);    return 0;}void slove(int s){    memset(d,INF,sizeof(d));    memset(d2,INF,sizeof(d2));    d[s]=0;    priority_queue<P,vector<P>,greater<P> > pq;    pq.push(P(d[s],s));    while(!(pq.empty())){        P p=pq.top();        pq.pop();        if(d2[p.second]<p.first)            continue;        for(int i=0;i<ve[p.second].size();i++){            Node n=ve[p.second][i];            int dd=p.first+n.val;//这个地方就是让我一直wa的地方。。一开始写的dd=d[p.second]+n.val,结果一直wa。。后来终于反应过来,才意识到自己好蠢。。。这个题是要维护的次短路径!!所以这个地方并不一定要求是到某个点的最小路径。还有上边那个减小循环的地方,也是只用判断d2数组就行了。别的地方就只是一个普通的算法了。            if(d[n.en]>dd){                swap(dd,d[n.en]);                pq.push(P(d[n.en],n.en));            }            if(dd>d[n.en]&&dd<d2[n.en]){                d2[n.en]=dd;                pq.push(P(d2[n.en],n.en));            }        }    }}


原创粉丝点击