您的位置:首页 > 编程语言 > C语言/C++

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

2017-06-14 20:38 337 查看
这个题真的是卡了我一天之久。。。倒并不是说它难。有一个地方一直没注意到结果一直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 0x3f3f3f3f
typedef 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
);
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));
}
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c++ poj dijkstra 算法